MongoDB查询含重复type与end节点的Edges的Graph文档
解决MongoDB查询Graph文档的问题
需求回顾
要查询所有满足以下条件的文档:
- 文档的
type字段值为Graph - 文档的
graph.edges数组中,至少有两条不同的edge,它们的type和end属性值完全相同
推荐方案:使用聚合管道(高效无性能问题)
MongoDB的聚合管道比$where性能好得多,且无需执行JavaScript,适合处理这类数组匹配需求,具体代码如下:
db.collection.aggregate([ // 第一步:先过滤出type为Graph的文档,减少后续计算量 { $match: { type: "Graph" } }, // 第二步:处理edges数组,统计每个(type, end)组合的出现次数 { $addFields: { edgeGroups: { $map: { input: { $group: { input: "$graph.edges", id: { type: "$type", end: "$end" }, count: { $sum: 1 } } }, as: "group", in: "$$group.count" } } } }, // 第三步:筛选出存在出现次数>=2的edge组合的文档 { $match: { $expr: { $gt: [ { $max: "$edgeGroups" }, 1 ] } } }, // 可选:移除新增的edgeGroups字段 { $project: { edgeGroups: 0 } } ])
修正你原来的$where写法(不推荐,性能较差)
你原来的写法错误在于$where不能直接嵌套$function,$function是聚合表达式的一部分,不是$where的参数。如果一定要用JavaScript方式查询,可改成以下写法(需MongoDB支持$expr和$function,且性能不如聚合管道):
db.collection.find({ type: "Graph", $expr: { $function: { body: function(edges) { // 用对象统计每个(type, end)组合的出现次数,提前终止判断 const countMap = {}; for (const edge of edges) { const key = `${edge.type}-${edge.end}`; countMap[key] = (countMap[key] || 0) + 1; if (countMap[key] >= 2) return true; } return false; }, args: ["$graph.edges"], lang: "js" } } })
原写法失败原因
$where的参数只能是字符串形式的JavaScript代码或直接函数,不能是$function对象;同时你原查询未添加type: "Graph"的筛选条件,这两点共同导致了查询失败。
内容的提问来源于stack exchange,提问作者mcv
相关产品推荐
相关产品推荐

