【问题标题】:MongoDB match document where embeded document (array of objects) has (nested) array field occuring value only onceMongoDB匹配文档,其中嵌入式文档(对象数组)具有(嵌套)数组字段仅出现一次值
【发布时间】:2020-05-07 15:23:55
【问题描述】:

我的数据库中有以下架构

{
   _id: Number,
   reagents: [ //Array of objects (embedded) FIND IF certain tag in v_class occurred only once in array
       {
           _id: Number,
           v_class: Array, //A single array (string only): ['TEST','PREMIUM']
       },
       {
           _id: Number,
           v_class: Array, //A single array (string only): ['TEST','PREMIUM']
       },
       {
           _id: Number,
           v_class: Array, //A single array (string only): ['TEST','PREMIUM']
       }
   ],
   other_fields: other_values,
}

MongoPlayground

问题在于:

如何只找到那些文档,其中reagents 字段只有一项(试剂、嵌入文档),其中v_class 数组字段包含单词PREMIUM

因此,从上面选定的集合中,我只想拥有带有 _id: 2 的文档,因为它是 reagents 字段具有 THE ONLY 文档的唯一文档,其中字段名为 v_classPREMIUM 只出现一次。

UPD:我在$group阶段,MongoPlayground(组后)之后取得了一些简单的结果。所以就目前而言,我仍然需要找到 v_class 数组字段在其数组中出现 PREMIUM 值恰好一次的文档`

UPD2:我有新版本出现了。 MongoPlayground。这个查询很好,但它显示了所有PREMIUM,除了只出现一次。

【问题讨论】:

  • 在您的示例中,v_classreagents 数组中没有带有单个 PREMIUM 的文档。
  • 或者您想查找在任何 v_classes 中恰好出现一次“premium”的文档(不是 v_class 的唯一元素)?
  • @MickaelB。单并不意味着v_class 数组字段将只有["PREMIUM"] 值,这意味着我只需要找到一个文档,v_class = 包含PREMIUM 所以它可能像 `['X', '高级']
  • @Oleg,你说得对,非常感谢你指出我,我会更正描述。

标签: javascript mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

$sum 需要一个数值才有意义。

获得总和后,额外的$match 阶段可以将总和与 1 进行比较。

https://mongoplayground.net/p/TKQowD-vd0f

【讨论】:

  • 我刚刚找到它:mongoplayground.net/p/JWWy8LPgk5j 所以现在的关键问题是,我如何通过_id 返回原始文档,因为recipe_id 字段在我的情况下代表它?
  • 我想执行另一个 $lookup 将原始集合加入到现有结果中将实现这一目标。
  • 你有什么问题?
  • 那里没有问题,实际上你对$lookup 舞台原因是对的,起初我认为$out 可以从集合中返回原始文档,但它会创建一个新的文档集合具有特定名称。
【解决方案2】:

我已经找到了自己的方法来找到结果,与 Oleg 分开,但他是第一个,所以我支持他并接受他的变体作为答案。

我的查询只有一个区别。它返回原始文档本身,而不仅仅是参考字段。

完整查询:

db.collection.aggregate([
  {
    $match: {
      reagents: {
        $elemMatch: {
          _id: 12
        }
      }
    }
  },
  {
    $group: {
      _id: {
        v_class: "$reagents.v_class",
        recipe_id: "$_id"
      },
      data: {
        $push: "$$ROOT"
      }
    }
  },
  {
    $unwind: "$_id.v_class"
  },
  {
    $match: {
      "_id.v_class": "PREMIUM"
    }
  },
  {
    $group: {
      _id: "$_id.recipe_id",
      count: {
        $sum: 1,

      },
      data: {
        "$first": "$data"
      }
    }
  },
  {
    $match: {
      count: 1
    }
  }
])

它通过 ID 在试剂 (Array) 字段中找到确切的项目,并且它的文档有一个 v_class (Array) 字段检查它的值/标签是否只出现一次。

MongoPlayground

【讨论】:

    猜你喜欢
    • 2017-02-20
    • 2021-05-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-05
    • 2021-04-14
    • 2020-03-06
    相关资源
    最近更新 更多