MongoDB位置操作符$查询异常,返回错误数组元素求助
问题:MongoDB数组匹配返回错误元素的原因及解决办法
文档结构
cart集合的单条文档结构如下:
{ _id: ObjectId("661fb9ddc2b236ae8703ba92"), display_id: '38bd6126-02a1-47b9-b567-00aaf2eb076f', user_id: ObjectId("661137f22a31832ceb92ddbc"), items: [ { product_id: ObjectId("6622376051d5886f39ac7365"), size: ObjectId("660d444d0d7716ee24129675"), qty: 3 }, { product_id: ObjectId("662214f8cc5306f999369e99"), size: ObjectId("660d444d0d7716ee24129675"), qty: 2 }, { product_id: ObjectId("662214f8cc5306f999369e99"), size: ObjectId("660d444d0d7716ee24129674"), qty: 2 } ], __v: 4 }
执行的查询语句
MongoDB原生查询
db.carts.find( { user_id: new ObjectId("661137f22a31832ceb92ddbc"), "items.product_id": new ObjectId("662214f8cc5306f999369e99"), "items.size": new ObjectId("660d444d0d7716ee24129675") }, {"items.$":1} )
Mongoose查询代码
const doc = await Cart.findOne({ user_id: user_id, "items.product_id": product_id, "items.size": oldSize }, {"items.$":1})
预期与实际结果
预期返回
{ product_id: ObjectId("662214f8cc5306f999369e99"), size: ObjectId("660d444d0d7716ee24129675"), qty: 2 }
实际返回
{ product_id: ObjectId("6622376051d5886f39ac7365"), size: ObjectId("660d444d0d7716ee24129675"), qty: 3 }
问题原因
你的查询条件是分别匹配数组中任意元素的product_id和size,只要文档中存在某个元素的product_id符合,同时存在某个元素的size符合,整个文档就会被匹配。而$占位符只会返回数组中第一个满足查询条件的元素——这里第一个元素的size刚好符合条件,所以被返回了,即便它的product_id不符合。
解决办法
需要用$elemMatch来指定数组元素的多个条件必须同时满足在同一个对象上,修正后的查询如下:
修正后的MongoDB原生查询
db.carts.find( { user_id: new ObjectId("661137f22a31832ceb92ddbc"), items: { $elemMatch: { product_id: new ObjectId("662214f8cc5306f999369e99"), size: new ObjectId("660d444d0d7716ee24129675") } } }, {"items.$":1} )
修正后的Mongoose代码
const doc = await Cart.findOne({ user_id: user_id, items: { $elemMatch: { product_id: product_id, size: oldSize } } }, {"items.$":1})
这样就能精准匹配到同时满足product_id和size的数组元素,返回你预期的结果。
内容的提问来源于stack exchange,提问作者ISHAN JARWAL
相关产品推荐
相关产品推荐

