Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb-从数组、匹配项属性或子数组项属性聚合项_Mongodb_Aggregation Framework - Fatal编程技术网

Mongodb-从数组、匹配项属性或子数组项属性聚合项

Mongodb-从数组、匹配项属性或子数组项属性聚合项,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我有以下结构的文件: { _id: "UNIQUE_ID", myarray: [ { mykey: '12345', // other fields }, { // other fields nestedarray: [ { mykey: '67890', // other fields } ] } ] } 我需要返回

我有以下结构的文件:

{
  _id: "UNIQUE_ID",
  myarray: [
    {
      mykey: '12345',
      // other fields
    },
    {
      // other fields
      nestedarray: [
        {
          mykey: '67890',
          // other fields
        }
      ]
    }
  ]
}
我需要返回
myarray
mykey
(在
myarray
nestedarray
的项目上)属于一组值的所有项目。例如,对于上面的文档,如果值集是
['12345,'67890']
,则应返回
myarray
中的两个项目

我使用以下代码来实现这一点:

collection.aggregate([
  {
    $match: {
      "_id": documentId,
      $or: [
        { "myarray": {$elemMatch: {"mykey": { $in: ['12345, '67890'] } } } },
        { "myarray.$.nestedarray": {$elemMatch: {"mykey": { $in: ['12345, '67890'] } }} }
      ]
    }
  },
  {
    $project: {
      myarray: {
        $filter: {
          input: '$myarray',
          as: 'arrayitem',
          cond: {
            $or: [
              { $eq: ["$$arrayitem.mykey", '12345'] },
              { $eq: ["$$arrayitem.nestedarray.[$].mykey", '12345'] }
            ]
          }
        }
      }
    }
  }
]);
但这只返回
mykey
myarray
级别匹配的项目(在
nestedarray
中不匹配)

我做错了什么

另外,如何在$filter函数中使用set
['12345',67890']
而不是单值
'12345'

澄清:

  • 如果
    mykey
    匹配在
    myarray
    中的项目上:包括此项目(此项目将没有
    nestedarray
    字段)
  • 如果
    mykey
    匹配在
    nestedarray
    中的项目上:包括
    myarray
    中包含
    nestedarray
    的项目(也包括
    nestedarray
    的全部内容)。
    myarray
    中的此项将没有
    mykey
    字段
示例:

数据:

值集:
['11111','22222']

预期查询结果:

{
  _id: "UNIQUE_ID",
  myarray: [
    {
      mykey: '11111',
      // other fields
    },
    {
      // other fields
      nestedarray: [
        {
          mykey: '22222',
          // other fields
        },
        {
          mykey: '84325',
          // other fields
        }
      ]
    }
  ]
}

您可以使用下面的聚合

db.collection.aggregate([
  { "$match": { "_id": documentId }},
  { "$project": {
    "myarray": {
      "$filter": {
        "input": {
          "$map": {
            "input": "$myarray",
            "as": "arrayitem",
            "in": {
              "mykey": "$$arrayitem.mykey",
              "nestedarray": "$$arrayitem.nestedarray",
              "aaaa": {
                "$filter": {
                  "input": "$$arrayitem.nestedarray",
                  "as": "vv",
                  "cond": { "$in": ["$$vv.mykey", ["12345", "67890"]] }
                }
              }
            }
          }
        },
        "as": "ff",
        "cond": {
          "$or": [
            { "$in": ["$$ff.mykey", ["12345", "67890"]] },
            { "$gte": [{ "$size": { "$ifNull": ["$$ff.aaaa", []] }}, 1] }
          ]
        }
      }
    }
  }},
  { "$project": { "myarray.aaaa": 0 }}
])
这是工作模式

您可以使用single,然后作为
cond
您可以直接检查
mykey
或用于数组

db.col.aggregate([
    {
        $project: {
            myarray: {
                $filter: {
                    input: "$myarray",
                    cond: {
                        $or: [
                            { $in: [ "$$this.mykey", ["11111", "22222"] ] },
                            { $anyElementTrue: [ 
                                { 
                                    $map: { 
                                        input: { $ifNull: [ "$$this.nestedarray", [] ] }, 
                                        as: "na", 
                                        in: { $in: [ "$$na.mykey", ["11111", "22222"] ] } 
                                    } 
                                } 
                                ] 
                            }
                        ]
                    }
                }
            }
        }
    }
])

如果
mykey
存在于
nestedarray
中,但不存在于
myArray
中,该怎么办?那么应该包括
myArray
中包含
nestedarray
的项,并且只包括匹配项从
nestedarray
应该包括在内OK,那么下面的答案对你有用。@AnthonyWinzlet实际上需要从
nestedarray
中选择所有项目(即使只有一个匹配)。所以基本上你不想筛选
nestedarray
数组?谢谢你的回答!在这种情况下,我应该保持
$match
与我在问题上发布的完全一致,还是应该放弃它(在这种情况下,如何匹配文档_id)?使用单个
$match
\u id
。剩下的事情,
$filter
可以。尝试了,但我得到了以下错误
errmsg:“$size的参数必须是数组,但类型为:null”
再次更新了我的答案。唯一的问题是它没有为
myarray
项带来其他属性(仅
mykey
nestedarray
)。我正在想办法。谢谢你的回答!尝试过了,但这只返回了带有非嵌套的
mykey
@GCSDC的项目,这对我来说有点不清楚,修改(并简化)了我的答案,适用于您的示例这就是我要找的!非常感谢你!
db.col.aggregate([
    {
        $project: {
            myarray: {
                $filter: {
                    input: "$myarray",
                    cond: {
                        $or: [
                            { $in: [ "$$this.mykey", ["11111", "22222"] ] },
                            { $anyElementTrue: [ 
                                { 
                                    $map: { 
                                        input: { $ifNull: [ "$$this.nestedarray", [] ] }, 
                                        as: "na", 
                                        in: { $in: [ "$$na.mykey", ["11111", "22222"] ] } 
                                    } 
                                } 
                                ] 
                            }
                        ]
                    }
                }
            }
        }
    }
])