MongoDB图查询:查找存在A->B但不存在B->A的节点对
MongoDB查询单向边节点对的实现方法
要找出存在A→B边但不存在B→A边的节点对,用MongoDB的聚合框架就能直接实现,具体步骤和查询语句如下:
核心思路
先给每条边查找对应的反向边(B→A),然后筛选出没有反向边的记录,最后去重得到唯一的单向节点对。
具体查询语句
db.training_sample.aggregate([ // 第一步:过滤掉机场代码为空的无效记录(可选,根据数据情况调整) { $match: { src_airport: { $ne: "" }, dst_airport: { $ne: "" } } }, // 第二步:查找当前边的反向边(B→A的记录) { $lookup: { from: "training_sample", let: { current_src: "$src_airport", current_dst: "$dst_airport" }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ["$src_airport", "$$current_dst"] }, { $eq: ["$dst_airport", "$$current_src"] } ] } } } ], as: "reverse_edges" } }, // 第三步:筛选出没有反向边的记录 { $match: { reverse_edges: { $size: 0 } } }, // 第四步:对重复的(A,B)对去重(同一条航线可能有多个航空公司) { $group: { _id: { src: "$src_airport", dst: "$dst_airport" }, // 可选:保留该航线的第一个航空公司信息 airline: { $first: "$airline.name" } } }, // 第五步:调整输出格式,让结果更直观 { $project: { _id: 0, src_airport: "$_id.src", dst_airport: "$_id.dst", airline: "$airline" } } ])
各阶段说明
- $match(第一阶段):提前过滤无效数据,比如空的机场代码,减少后续计算量。
- $lookup:通过子管道精准匹配反向边,确保找到的是从B到A的记录,而不是B到其他机场的记录。
- $match(第二阶段):
reverse_edges: { $size: 0 }表示当前边没有对应的反向边,正是我们要找的单向边。 - $group:因为同一条A→B航线可能有多个航空公司运营,这里对相同的(src,dst)对去重,只保留一组。
- $project:重新整理输出字段,去掉自动生成的_id,让结果更易读。
内容的提问来源于stack exchange,提问作者Fenrir
相关产品推荐
相关产品推荐

