【问题标题】:Mongoose unique results猫鼬独特的结果
【发布时间】:2018-09-30 18:28:22
【问题描述】:

我正在寻找一个查询,该查询将从我的 mongo 数据库中提取一组结果,但删除/忽略具有重复字段值的结果。

这里是 senario,我从 spotify api 中提取许多结果并将它们存储在我的数据库中,由于我所做的性质,我最终提取了许多相同的专辑,这些专辑共享一个id 字段。请注意,这不是 mongo _id 字段。

我想要的是,当用户构建可能包含这些重复项的查询时,消除拉取同一专辑的多个问题。

这是我目前的查询,它可以满足我的需求,但不会过滤掉重复项:

Albums.aggregate([
    { $match : { source_region : { $in: countries }}},
    { $skip  : offset },
    { $limit : limit }
])

起初我使用更典型的Collection.find().sort() 等并遇到distinct,但您不能将sort、limit 等与distinct 一起使用。

我也尝试过使用$group,但这似乎只是返回了我指定的字段,所以当我尝试类似:

{ $group : { _id : null, uniqueValues : { $addToSet : "$id" }}}

返回的唯一字段是 id 字段,当我需要大约 10-20 与该专辑关联时。

如果有人能指出正确的方向,那就太好了!

更新 1

这里是集合中一些文档的示例

{
  _id : ObjectId("5ad965a8bc349952904f7f31"),
  id : 0nEsaNZGpk0HIgY3OGCyR6,
  title : "some album",
  artist : "some artist
},
{
  _id : ObjectId("665fhFHJFjdjfud7d6f6"),
  id : 5JUSBHF&55sdfhjkf86sd,
  title : "another album",
  artist : "another artist
},
{
  _id : ObjectId("56&DFHJFHJJFJSgh76sdghhsd"),
  id : 0nEsaNZGpk0HIgY3OGCyR6,
  title : "some album",
  artist : "some artist
}

因此,如果这是我的数据,我只想返回共享 spotify 生成的 id 字段的文档之一。

【问题讨论】:

  • 你显然需要一个解释。那么究竟是什么让“文档”独一无二呢?我在这里看到$id 而不是$_id,但这是唯一的字段吗?以及如何处理其他“重复”的东西。
  • 是的,你需要解释的比你有的更多。因此,我提示您为您的问题添加更好的解释。此外,您可能需要刷新页面并再次阅读评论,因为您似乎只回复了部分内容。
  • 啊,是的,我没有看到您修改后的评论。我用一个示例 senario 更新了这个问题。对于您的第一条评论,id 字段是由 spotify 生成的,这是我要测试文档是否重复的字段。它与 mongo 生成的 _id 字段分开,后者已经是唯一的。
  • 晚了 1 秒。稍等我阅读,如果答案需要根据您的内容进行任何调整,那么我会添加它。不过有一件事,Mongoose 将 _id 和 id 视为同一件事。 MongoDB 认为它们是不同的,但如果你把 mongoose 命名为这样,你就会遇到问题。
  • 啊很高兴知道!为了清楚起见,我正在考虑更改id,但现在我肯定会。

标签: javascript node.js mongodb mongoose aggregation-framework


【解决方案1】:

既然你已经很沉默了,那我们就只好做一些假设了。

除了您期望文档中的“一个”属性来定义“唯一”(_id 之外,它已经这样做了)之外,没有其他数据可以继续,那么您要做的就是这样:

Albumns.aggregate([
  { "$group": {
    "_id": "$uniqueProp",
    "doc": { "$first": "$$ROOT" }
  }},
  { "$replaceRoot": { "newRoot": "$doc" } }
  { "$skip": offset },
  { "$limit": limit }
])

或者你想做的任何其他操作。

对于$group 管道阶段,_id 属性决定了您“分组”的结果的“唯一性”。此键中指定的任何内容都不会产生超过 1 个相同的值。你甚至可以有一个复合值:

  { "$group": {
    "_id": { "firstField": "$firstField", "secondField": "$secondField" },
    "doc": { "$first": "$$ROOT" }
  }}

所以里面的东西都是独特的。

每当您“分组”时,除了_id 键之外,您还需要一个“累加器”。所以在这里我们使用$first 来简单地获取我们指定的任何值的第一个结果,并在此处使用$$ROOT 来处理整个文档。

现代版本有$replaceRoot 来清理文档。如果您没有,那么您可以$project 每个字段,或者直接使用"doc" 属性下的输出。

【讨论】:

  • 终于有时间做这个了,效果很好!唯一的问题似乎是,由于跳过和限制,它只会使返回的结果独一无二,在我的例子中,一次 20 个。因此,当您浏览前端的结果时,仍然会出现重复项。我取消了限制并跳过并获得了一个适当的独特设置,所以我认为我只需要找出一种不同的方式来实现我正在寻找的东西。感谢您的简洁回答!
猜你喜欢
  • 2022-07-22
  • 2014-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-22
  • 2023-03-26
  • 1970-01-01
相关资源
最近更新 更多