MongoDB多条件Lookup关联查询无结果问题排查求助
MongoDB多条件Lookup查询无结果问题排查
我有两个集合Collection1和Collection2,原本基于myLocalId匹配subarray._id的基础Lookup查询可以正常运行。现在想实现基于id和type的多条件关联查询,尝试了以下带内嵌管道的Lookup语句,但没有得到任何结果:
{ from: "collection2", let: { myLocalId: "$myLocalId", myType: "$type", }, pipeline: [ { $match: { $expr: { $and: [ { $eq: [ "$subarray._id", "$$myLocalId", ], }, { $eq: [ "$subarray.type", "$$myType", ], }, ], }, }, }, ], as: "results", }
但硬编码值时能得到部分响应,请问我哪里操作有误?
集合示例数据
Collection1数据:
[ { "_id": { "$oid": "640e59c540bb4d036df16808" }, "myLocalId": "id1c1", "title": "id1c1 title", "type": "type1" }, { "_id": { "$oid": "640e59da40bb4d036df1680a" }, "myLocalId": "id2e3", "title": "id2e3 title3", "type": "type1" } ]
Collection2数据:
[ { "_id": { "$oid": "640e58c940bb4d036df16801" }, "myLocalId": "id2a2", "title": "id2a2 title", "type": "type1", "subarray": [ { "_id": "id2c2", "displayName": "id2c2 for id2a2", "type": "type1" }, { "_id": "id2c4", "displayName": "id2c4 for id2a2", "type": "type1" } ] }, { "_id": { "$oid": "640e58f140bb4d036df16803" }, "myLocalId": "id2a3", "type": "type1", "title": "id2a3 title3", "subarray": [ { "_id": "id1c1", "displayName": "id1c1 for id2a3", "type": "type1" }, { "_id": "id2c2", "displayName": "id2c2 for id2a3", "type": "type1" } ] }, { "_id": { "$oid": "640e590d40bb4d036df16805" }, "myLocalId": "id2a1", "type": "type1", "title": "id2a1 title", "subarray": [ { "_id": "id2c2", "type": "type1", "displayName": "id2c2 for id2a1" } ] } ]
问题原因与修正方案
你的错误在于直接用$subarray._id和$subarray.type进行等值匹配。因为subarray是数组字段,$subarray._id会返回整个数组中所有元素的_id组成的数组(比如["id1c1", "id2c2"]),用这个数组和单个字符串$$myLocalId比较,永远不会相等,自然查不到结果。
要实现“数组中存在某个元素同时满足_id和type匹配”的逻辑,需要用数组操作符判断数组内是否有符合双条件的元素,以下是两种可行的修正方案:
修正方案1:使用$filter+判断非空数组
{ from: "collection2", let: { myLocalId: "$myLocalId", myType: "$type" }, pipeline: [ { $match: { $expr: { $ne: [ { $filter: { input: "$subarray", cond: { $and: [ { $eq: ["$$this._id", "$$myLocalId"] }, { $eq: ["$$this.type", "$$myType"] } ] } } }, [] ] } } } ], as: "results" }
修正方案2:使用$anyElementTrue+$map
{ from: "collection2", let: { myLocalId: "$myLocalId", myType: "$type" }, pipeline: [ { $match: { $expr: { $anyElementTrue: { $map: { input: "$subarray", as: "item", in: { $and: [ { $eq: ["$$item._id", "$$myLocalId"] }, { $eq: ["$$item.type", "$$myType"] } ] } } } } } } ], as: "results" }
验证结果
修正后,Collection1中第一条数据(myLocalId: "id1c1",type: "type1")会匹配到Collection2中的第二条数据,因为它的subarray里存在{_id: "id1c1", type: "type1"}的元素;第二条数据(myLocalId: "id2e3")没有匹配项,results数组为空。
内容的提问来源于stack exchange,提问作者user2842284
相关产品推荐
相关产品推荐

