根据数组中的条件从数组中获取不同的值

时间:2017-10-12 18:29:09

标签: mongodb mongodb-query aggregation-framework

我有一个包含这样文件的集合:

{
"_id" : ObjectId("59df91dae4b03289d79efb4e"),
  "name" : "TEST",
  "payload" : [ 
    {
      "_id" : "ABC",
      "status": "FALSE"
    },
    {
      "_id":"DEF",
     "status": "TRUE"
    },
    {
      "_id" : "XYZ",
     "status": "NULL"
    }
  ]
}

我正在尝试查找状态为TRUE / FALSE的所有payload._id。 预期结果是

["ABC","DEF"]

到目前为止,我有类似的东西。

db.collection.distinct('payload._id',{"_id" : "TEST"})

不确定如何为数组中的元素添加条件。

2 个答案:

答案 0 :(得分:2)

.distinct()的查询条件适用于"文档选择"而不是包含的数组条目"在"该文件。如果您需要"过滤"数组内容然后你应用.aggregate()代替,以及一点点后期处理,只获得"值"在数组响应中。

db.collection.aggregate([
  { "$match": { "_id": "TEST" } },
  { "$unwind": "$payload" },
  { "$match": { "payload.status": { "$in": ["TRUE","FALSE"] } } },
  { "$group": { "_id": "$payload._id" } },
]).map( d => d._id );

主要部分是$unwind管道阶段,主要是因为您希望数组中的值稍后用作$group的关键字。这实质上为每个数组成员生成一个新文档,但每个文档只包含该数组成员。它正常化"非正规化"对于包含数组的MongoDB结构。

接下来就是以下$match管道,它与任何查询一样,只选择符合条件的文档。由于所有阵列成员现在都是"文件"然后排除非匹配条目(作为文档)。你可以选择使用$filter来提取数组,但由于我们需要$unwind用于下一阶段,我们也可以简单地$match

此时,您只剩下符合条件的数组条目。 $group是获得" distinct"因此,通常您可以在更广泛的选择范围内执行此操作,而不仅仅是单个文档或此处值尚未区分的任何内容。所以这只是保持.distinct()完全相同的行为。

最后,由于.aggregate()的输出与.distinct()的设计不同,因为它返回"文件"在结果中,我们只使用.map()方法处理游标结果并仅返回"值"从特定的文档属性作为"数组"。

答案 1 :(得分:1)

  

我正在尝试查找状态为TRUE / FALSE

的所有payload._id

您要运行的查询是:

db.collection.distinct('payload._id', { 
  'payload.status': { $in: ["TRUE", "FALSE"] } 
})

更简洁的方法是:

db.collection.distinct('payload._id', { 
  $or: [
    {'payload.status': "TRUE" },
    {'payload.status': "FALSE" }
  ]  
})