【问题标题】:Mongo aggregate search results based on unique subcollection property with count?Mongodb基于具有计数的唯一子集合属性聚合搜索结果?
【发布时间】:2019-09-02 07:25:55
【问题描述】:

我一直在努力思考如何做到这一点已经好几个小时了,我有一个名为“Jobs”的集合——在里面,他们有一个子集合“Site”,即 Jobs.site。此站点子集合具有属性“UNID”。

我正在尝试基于文本搜索从数据库中检索文档,效果很好。

但我试图仅检索基于该 Job.Site.UNID 的 UNIQUE 文档,并且可能将计数添加为额外属性。结果应如下所示:

Job: { site: { field1: 'EXAMPLE', UNID: 'SITEID', count: 5 } }

这意味着作业集合中有 5 个作业具有该 site.UNID。

这是我目前所拥有的:

[
// GETTING DOCS BASED ON TEXT SEARCH RESULTS
    {
      $match: {
        // clientId: req.user.client_id,
        $text: { $search: body.searchTerms }
      }
    },
// SORTING THEM BASED ON TEXTSCORE
    { $sort: { score: { $meta: 'textScore' } } },
// THE PROBLEMATIC GROUPING PART
    { $group: { site: { UPRN: '$UPRN', myCount: { $sum: 1 } } } },
// I ONYL WANT TO GET 20 DOCS AT A TIME
    { $limit: 20 },
// THE DATA THAT I WANT IN MY DOCUMENTS, MAYBE COUNT WOULD COME HERE?
    {
      $project: {
        site: true,
        score: { $meta: 'textScore' }
      }
    },
// GETTING RID OF POOR MATCHES BASED ON A SCORE CALCULATED IN ANOTHER 
// FUNCTION BASED ON THE NUMBER OF WORDS IN THE TEXT SEARCH
    {
      $match: {
        score: { $gt: matchScore }
      }
    }
  ]

这里是The field 'site' must be an accumulator object@

所以我无法弄清楚正确处理该子集合属性的语法。

编辑:V2 感谢@Anthony 完美工作并对其进行了彻底测试,但它似乎没有计算工作总数,它始终为 1 或我在 $sum 中设置的任何值:但有 200 多个结果,仍在工作就可以了。

 { $match: { $text: { $search: body.searchTerms } } },
    { $sort: { $score: { $meta: 'textScore' } } },
    // { $match: { score: { $gt: 0.1 } } },
    {
      $group: {
        _id: '$UNID',
        counter: { $sum: 1 },
        score: { $first: { $meta: 'textScore' } },
        title: { $first: '$title' },
        postcode: { $first: '$postcode' },
        addressLine1: { $first: '$addressLine1' },
        city: { $first: '$city' },
        projectName: { $first: '$projectName' },
        jobsCount: { $sum: '$counter' }
      }
    },
    { $limit: 20 },
    {
      $project: {
        UNID: '$_id',
        title: '$title',
        postcode: '$postcode',
        addressLine1: '$addressLine1',
        projectName: '$projectName',
        city: '$city',
        score: 1,
        jobsCount: true
      }
    }

样本数据:


{
  "_id": "randomString0",
  "title": "Quality",
  "site": {
    "_id": "rKFRbvH8CEbJYdzDs",
    "title": "Title 1",
    "addressLine1": "address1",
    "UNID": "001",
    "city": "cityName",
    "createdAt": null
  }
},
{
  "_id": "randomString1",
  "title": "Some2123",
  "site": {
    "_id": "rKFRbvH8CEbJYdzDs",
    "title": "Title 1",
    "addressLine1": "address1",
    "UNID": "001",
    "city": "cityName",
    "createdAt": null
  }
},
{
  "_id": "randomString2",
  "title": "Random title",
  "site": {
    "_id": "rKFRbvH8CEbJYdzDs",
    "title": "Title 1",
    "addressLine1": "address1",
    "UNID": "001",
    "city": "cityName",
    "createdAt": null
  }
},
{
  "_id": "randomString3",
  "title": "Another unique job",
  "site": {
    "_id": "rKFRbvH8CEbJYdzDs",
    "title": "Title 1",
    "addressLine1": "address1",
    "UNID": "001",
    "city": "cityName",
    "createdAt": null
  }
},
{
  "_id": "randomString4",
  "title": "Other thing",
  "site": {
    "_id": "rKFRbvH8CEbJYdzDs",
    "title": "Title 1",
    "addressLine1": "address1",
    "UNID": "001",
    "city": "cityName",
    "createdAt": null
  }
},
{
  "_id": "randomString5",
  "title": "Something else",
  "site": {
    "_id": "rKFRbvH8CEbJYdzDs",
    "title": "Title 1",
    "addressLine1": "address1",
    "UNID": "001",
    "city": "cityName",
    "createdAt": null
  }
}

如您所见,站点数据在所有这 5 个文档下始终是唯一的,但计数器应该计算有多少文档具有相同的唯一性

【问题讨论】:

    标签: node.js mongodb mongoose aggregation-framework


    【解决方案1】:

    $group 阶段,_id(您想要分组的依据)表达式是必需的表达式。而且只有少数accumulators 可以与$group 聚合阶段一起使用。

    所以你的聚合一定是这样的

    [
      { "$match": { "$text": { "$search": body.searchTerms }}},
      { "$sort": { "score": { "$meta": "textScore" } } },
      { "$match": { "score": { "$gt": matchScore }}},
      { "$group": {
        "_id": "$UPRN",
        "myCount": { "$sum": 1 },
        "score": { "$first": "$score" }
      }},
      { "$limit": 20 },
      { "$project": {
        "site": "$_id",
        "score": 1,
        "myCount": 1
      }}
    ]
    

    【讨论】:

    • 哇,谢谢@Anthony——真的让我摆脱了僵局。 - 从你发布答案的那一刻起,我一直在尝试使用它并查看数据! -- 目前,即使我输入了 site: true 并且 score 似乎总是为空,在 $project 下也不会返回站点数据——将继续尝试,谢谢!
    • 另外——让它不同确实有效,但计数目前不计算工作的数量——无论我如何在“myCount”下投射东西,它都默认为 1 嗯
    • 你能发布一些样本集吗?然后我会告诉你确切的输出。
    • 现在一切正常!我正在获取数据,我只得到独特的东西,但是 count $sum 似乎不起作用。我还在计算所说的 UNID 的总数,我看到/知道有 200 多个文档都具有相同的 UNID,我只得到 2 个带有站点数据的文件,这正是我想要的,但它不计算它们,它总是返回 1 或我在 $sum 中设置的任何值:1
    • 尝试移除第二个比赛阶段。我认为您的数据被阻止了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-10
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多