MongoDB findOne用法疑问:如何查询嵌套数组products中的prod_id
解决MongoDB findOne查询数组嵌套字段的问题
嘿,我明白你遇到的问题了——你想查询购物车集合中特定用户下包含某个商品ID的文档,但原来的写法会因为数组元素的完全匹配要求而得不到正确结果。
问题出在哪?
你原来的查询里直接用products: [{ prod_id: Item.idProd }],MongoDB会把这个当作完全匹配数组中的某个元素,也就是说它要求数组里有一个元素和{ prod_id: Item.idProd }完全一致(连qty字段都得不存在或者和这个对象完全一样),但实际上你只需要检查数组里有没有prod_id等于目标值的元素,不管qty是什么。
正确的两种写法
方法1:使用$elemMatch(适合多条件匹配数组元素)
如果你以后需要同时匹配数组元素的多个字段(比如prod_id和qty),$elemMatch是更通用的方式:
ShoppingCart.findOne( { user_id: Item.idUser, products: { $elemMatch: { prod_id: Item.idProd } } }, callback );
它会检查products数组中是否存在至少一个元素满足prod_id等于Item.idProd的条件。
方法2:直接使用点符号(单条件匹配更简洁)
当你只需要匹配数组元素的单个字段时,MongoDB支持直接用点路径来定位嵌套字段,写法更简单:
ShoppingCart.findOne( { user_id: Item.idUser, "products.prod_id": Item.idProd }, callback );
这种写法和上面的$elemMatch效果一致,MongoDB会自动遍历products数组,查找存在prod_id等于目标值的文档。
额外补充:只返回匹配的数组元素
如果你不仅要找到文档,还想只返回products数组中匹配的那个元素(而不是整个数组),可以加上投影参数:
ShoppingCart.findOne( { user_id: Item.idUser, "products.prod_id": Item.idProd }, { "products.$": 1, user_id: 1 }, // 只保留匹配的products元素和user_id字段 callback );
这里的$是投影操作符,会返回数组中第一个匹配查询条件的元素。
内容的提问来源于stack exchange,提问作者Ian Phill
相关产品推荐
相关产品推荐

