MongoDB 3.4.2多层嵌套结构查询:检索关联指定List Id的用户
问题根源
你之前尝试的$elemMatch写法不生效,是因为Tags.Entries.ContactLists.Values是嵌套对象结构(键为"0"、"1"、"2"这类字符串序号),而$elemMatch仅适用于数组类型字段,自然无法匹配任意键下的Value属性。
可用解法(适配MongoDB 3.4.2版本)
方案1:聚合查询(推荐,性能更优)
MongoDB 3.4版本已支持$objectToArray运算符,可以将嵌套对象转为数组后做匹配,写法如下:
仅查询匹配目标GUID的所有Contact文档
db.getCollection('Contacts').aggregate([ // 将Values对象转为结构为[{k: "0", v: {Value: "...", DateTime: ISODate()}}]的数组 { $addFields: { contactListArr: { $objectToArray: "$Tags.Entries.ContactLists.Values" } } }, // 过滤出数组中存在对应GUID的文档 { $match: { "contactListArr.v.Value": "{28BECCD3-476B-4B1D-9A75-02E59EF21286}" } }, // 移除临时生成的辅助字段,还原原始文档结构 { $project: { contactListArr: 0 } } ])
仅返回匹配的GUID条目
如果需要过滤掉其他不匹配的List ID条目,仅保留命中的内容,可以扩展聚合逻辑:
db.getCollection('Contacts').aggregate([ { $addFields: { contactListArr: { $objectToArray: "$Tags.Entries.ContactLists.Values" } } }, { $match: { "contactListArr.v.Value": "{28BECCD3-476B-4B1D-9A75-02E59EF21286}" } }, // 过滤出仅匹配的条目 { $addFields: { matchedContactList: { $filter: { input: "$contactListArr", as: "item", cond: { $eq: ["$$item.v.Value", "{28BECCD3-476B-4B1D-9A75-02E59EF21286}"] } } } } }, // 自定义返回字段,可按需增减 { $project: { _id: 1, matchedContactList: 1 } } ])
方案2:JS遍历查询(适合小数据量临时查询)
你之前写的forEach逻辑是修改文档值,而非查询匹配文档,正确的遍历写法如下:
const targetId = "{28BECCD3-476B-4B1D-9A75-02E59EF21286}"; const result = []; db.getCollection('Contacts').find().forEach(doc => { const listValues = doc.Tags?.Entries?.ContactLists?.Values; if (!listValues) return; // 遍历所有序号键 for (const idx in listValues) { if (listValues[idx].Value === targetId) { result.push(doc); break; } } }); // 输出结果 printjson(result);
内容的提问来源于stack exchange,提问作者Javz
相关产品推荐
相关产品推荐

