【问题标题】:Filter the sub array of an array by some criteria按某些条件过滤数组的子数组
【发布时间】:2017-06-02 12:17:53
【问题描述】:

您好,有一份格式如下的文件:

{
   "_id":"someId",
   "someArray":[
      {
         "subId":1,
         "subArray":[
            {
               "field1":"A",
               "filterMe":"NO"
            },
            {
               "field1":"B",
               "filterMe":"YES"
            }
         ]
      },
      {
         "subId":2,
         "subArray":[
            {
               "field1":"C",
               "filterMe":"YES"
            },
            {
               "field1":"D",
               "filterMe":"NO"
            }
         ]
      }
   ]
}

如何根据某些条件过滤子数组。如果字段 filterMe 为“YES”,则示例过滤掉子数组。所以最后输出的json应该是这样的

{
   "_id":"someId",
   "someArray":[
      {
         "subId":1,
         "subArray":[
            {
               "field1":"A",
               "filterMe":"NO"
            }
         ]
      },
      {
         "subId":2,
         "subArray":[
            {
               "field1":"D",
               "filterMe":"NO"
            }
         ]
      }
   ]
}

我尝试了以下方式,但是它过滤了整个子数组。

db.testJson.aggregate([
    { $project: {
        'someArray.subArray': {
          $filter: {
            input: '$someArray.subArray',
            as: 'input',
            cond: {$eq: ["$$input.filterMe", "YES"]}
        }}
    }}
]);

【问题讨论】:

  • 看看这是否有帮助。 stackoverflow.com/questions/29071748/…
  • @Veeram 这不是这里要问的
  • @Neil Lunn 被推荐的帖子有一个答案与您当前的答案完全一样,没有额外的外部$filter。我错过了什么?

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

您只需要在 $map 中添加一个 $filter

db.junk.aggregate([
  { "$project": {
    "someArray": {
      "$filter": {
        "input": {
          "$map": {
            "input": "$someArray",
             "as": "some",
             "in": {
               "subId": "$$some.subId",
               "subArray": {
                 "$filter": {
                   "input": "$$some.subArray",
                   "as": "sub",
                   "cond": { "$ne": [ "$$sub.filterMe", "YES" ] }
                 }
               }
             }
          }
        },
        "as": "some",
        "cond": { "$gt": [ { "$size": "$$some.subArray" }, 0 ] }
      }
    }
  }}
])

生产:

{
        "_id" : "someId",
        "someArray" : [
                {
                        "subId" : 1,
                        "subArray" : [
                                {
                                        "field1" : "A",
                                        "filterMe" : "NO"
                                }
                        ]
                },
                {
                        "subId" : 2,
                        "subArray" : [
                                {
                                        "field1" : "D",
                                        "filterMe" : "NO"
                                }
                        ]
                }
        ]
}

我实际上将它包装在一个额外的$filter 中以删除任何someArray 条目,其中过滤后的subArray 最终为空。里程可能会因您想要做的事情而有所不同。

【讨论】:

  • 在条件下如何使用 $exists 而不是 $ne?
  • @SparkOn 不确定您的意思。在您的问题的背景下,您要么想要平等,要么想要不平等。 $exists 的“逻辑”形式是 $ifNul,但这不适用于此处。请小心,因为如果您的真实数据与您提出的问题不同,那么尝试应用不同的数据可能不会得到相同的结果。如果您还有其他问题,则应改为Ask a new Question。这样就清楚多了。
猜你喜欢
  • 2021-05-09
  • 2021-10-20
  • 2010-12-02
  • 1970-01-01
  • 1970-01-01
  • 2016-12-19
  • 1970-01-01
相关资源
最近更新 更多