You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB聚合查询取最早重复文献返回Null,求排查错误原因

MongoDB聚合查询错误分析:筛选同一作者下最早发表的重复标题文献

问题描述

我拥有名为article_titles的MongoDB集合,其中存在重复的文献标题,需求是筛选出同一作者下最早发表的文献。集合数据如下:

{ "_id" : ObjectId("6375dbf89a70ce15b7c51172"), "title" : "Visualizing Graphs and Clusters as Maps", "year" : 2005, "name" : "amir" }
{ "_id" : ObjectId("6375dbf89a70ce15b7c5118a"), "title" : "Visualizing Dynamic Data with Maps", "year" : 2012, "name" : "amir" }
{ "_id" : ObjectId("6375dbf89a70ce15b7c511ac"), "title" : "Visualizing Cartograms: Goals and Task Taxonomy", "year" : 2015, "name" : "kobourov" }
{ "_id" : ObjectId("6375dbf99a70ce15b7c60293"), "title" : "Upward straight-line embeddings of directed graphs into point sets", "year" : 2008, "name" : "hossain" }
{ "_id" : ObjectId("6375dbf99a70ce15b7c738c7"), "title" : "Upward straight-line embeddings of directed graphs into point sets", "year" : 2010, "name" : "hossain" }

其中作者hossain有两篇同标题、不同发表年份的文献,我尝试使用以下聚合查询获取最早的那篇:

db.article_titles.aggregate([{$sort:{year:-1}},{$group:{_id:{title:"$title",name:"$name",year:{$first:"$year"}}}}])

但该查询返回Null值,想了解我的操作哪里存在错误?

错误原因

  • 排序方向错误:你用{$sort:{year:-1}}按年份降序排列,此时$first会取到每组中最新年份的记录,而你需要的是最早发表的,应该改为升序排序{$sort:{year:1}}。
  • 分组依据错误:你将year:{$first:"$year"}包含在_id字段中,_id是分组的唯一标识,这会导致每条记录因年份不同而单独成组,根本无法聚合同一作者同一标题的重复记录,最终返回的结果不符合预期。

正确的聚合查询

方法一:先排序再分组取第一条

通过升序排序确保每组第一条是最早的记录,再按作者和标题分组提取:

db.article_titles.aggregate([
  // 按年份升序排列,让最早的记录排在每组最前面
  {$sort: {year: 1}},
  // 按作者和标题分组,取每组的第一条完整记录
  {$group: {
    _id: {title: "$title", name: "$name"},
    earliestArticle: {$first: "$$ROOT"}
  }},
  // 将结果替换为完整的文献记录,方便查看
  {$replaceRoot: {newRoot: "$earliestArticle"}}
])

方法二:先分组找最小年份再关联原数据

先统计每个作者每个标题的最早年份,再匹配原集合获取完整记录:

db.article_titles.aggregate([
  // 分组获取每个作者每个标题的最小发表年份
  {$group: {
    _id: {title: "$title", name: "$name"},
    minYear: {$min: "$year"}
  }},
  // 关联原集合,匹配对应作者、标题和年份的记录
  {$lookup: {
    from: "article_titles",
    localField: ["_id.title", "_id.name", "minYear"],
    foreignField: ["title", "name", "year"],
    as: "earliestArticle"
  }},
  // 展开关联结果
  {$unwind: "$earliestArticle"},
  // 替换根节点为完整的文献记录
  {$replaceRoot: {newRoot: "$earliestArticle"}}
])

内容的提问来源于stack exchange,提问作者user110920

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 08:15:27