Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.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_Mongodb Query_Aggregation Framework - Fatal编程技术网

Mongodb 如何选择数组项包含在数组值中的文档?

Mongodb 如何选择数组项包含在数组值中的文档?,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我在mongodb(3.0)中有收藏: 我想查找具有m属性的文档,其中m._t包含['type1','type2'] 像这样: { _id: 1, m: [{_id:11, _t: 'type1'}, {_id:12, _t: 'type2'}] }, { _id: 2, m: [{_id:21, _t: 'type1'}] } 我尝试使用$and$elemMatch,但无法获得所需的结果。 如何使用find()执行此操作? 请帮帮我

我在mongodb(3.0)中有收藏:

我想查找具有m属性的文档,其中m._t包含['type1','type2']

像这样:

{
    _id: 1, 
    m: [{_id:11, _t: 'type1'},
        {_id:12, _t: 'type2'}]
},    
{
    _id: 2, 
    m: [{_id:21, _t: 'type1'}]
}
我尝试使用$and$elemMatch,但无法获得所需的结果。 如何使用find()执行此操作? 请帮帮我!谢谢

由于运算符将查询结果中
m
数组字段的内容限制为仅包含与条件匹配的第一个元素,因此以下操作将仅返回具有第一个匹配元素的数组

{
     "_id" : 11,
    "_t" : "type1"
}

使用投影进行查询:

db.collection.find(
    { 
        "m._t": {
            "$in": ["type1", "type2"]
        }
    },
    {
        "m": {
            "$elemMatch": {
                "_t": {
                    "$in": ["type1", "type2"]
                }
            }
        }
    }
)
结果

/* 0 */
{
    "_id" : 1,
    "m" : [ 
        {
            "_id" : 11,
            "_t" : "type1"
        }
    ]
}

/* 1 */
{
    "_id" : 2,
    "m" : [ 
        {
            "_id" : 21,
            "_t" : "type1"
        }
    ]
}
您可以采取的一种方法是,其中管道将由一个操作符组成,类似于上面的find查询来过滤初始文档流。下一个管道步骤将是关键的操作符,它使用另一个操作符“拆分”要进一步精简的数组元素,然后是最后的管道,通过使用累加器操作符恢复原始数据结构

以下说明了此路径:

db.collection.aggregate([
    {
        "$match": {
            "m._t": {
                "$in": ["type1", "type2"]
            }
        }
    },
    {
        "$unwind": "$m"
    },
    {
        "$match": {
            "m._t": {
                "$in": ["type1", "type2"]
            }
        }
    },
    {
        "$group": {
            "_id": "$_id",
            "m": {
                "$push": "$m"
            }
        }
    }
])
样本输出:

/* 0 */
{
    "result" : [ 
        {
            "_id" : 2,
            "m" : [ 
                {
                    "_id" : 21,
                    "_t" : "type1"
                }
            ]
        }, 
        {
            "_id" : 1,
            "m" : [ 
                {
                    "_id" : 11,
                    "_t" : "type1"
                }, 
                {
                    "_id" : 12,
                    "_t" : "type2"
                }
            ]
        }
    ],
    "ok" : 1
}
要获得“过滤”的结果,使用聚合管道是最快的方法:

db.junk.aggregate([
{“$match”:{“m.\u t”:{“$in”:[“type1”,“type2”]}},
{“$redact”:{
“$cond”:{
“如果”:{
“$or”:[
{“$eq”:[{“$ifNull”:[“$\t”,“type1”]},“type1”]},
{“$eq”:[{“$ifNull”:[“$\t”,“type2”]},“type2”]}
],
},
“然后”:“$$down”,
“else”:“$$PRUNE”
}
}}
])
$redact
操作符为文档设置逻辑过滤器,该过滤器也可以遍历到数组级别。请注意,这在文档的所有级别上都是匹配的,因此请确保没有其他元素共享此名称

查询用于选择,就像逻辑筛选器使用一样。任何不匹配的内容都会被“删减”

{
“_id”:1,
“m”:[
{
“_id”:11,
_t:“类型1”
},
{
“_id”:12,
_t:“类型2”
}
]
}
{ 
“_id”:2,
“m”:[{u id:21,”“t”:“type1”}]
}
简短、甜蜜、简单

有点麻烦,但比较安全的方法是使用此构造并过滤结果:

db.junk.aggregate([
{“$match”:{“m.\u t”:{“$in”:[“type1”,“type2”]}},
{“$project”:{
“m”:{
“$setDifference”:[
{“$map”:{
“输入”:“$m”,
“as”:“el”,
“在”:{
“$cond”:{
“如果”:{
“$or”:[
{“$eq”:[“$$el._t”,“type1”]},
{“$eq”:[“$$el.\u t”,“type2”]}
]
},
“然后”:“$$el”,
“else”:false
}
}
}},
[错误]
]
}
}}      
])
$map
针对每个元素计算条件,而
$setDifference
删除返回
false
而非数组内容的任何条件。非常类似于上面的修订版,但它只是专门处理一个数组,而不是整个文档

在未来的MongoDB版本中(目前在开发版本中可用),将有
$filter
操作符,这非常简单:

db.junk.aggregate([
{“$match”:{“m.\u t”:{“$in”:[“type1”,“type2”]}},
{“$project”:{
“m”:{
“$filter”:{
“输入”:“$m”,
“as”:“el”,
“条件”:{
“$or”:[
{“$eq”:[“$$el._t”,“type1”]},
{“$eq”:[“$$el.\u t”,“type2”]}
]
}
}
}
}}
])
这将简单地删除任何与指定条件不匹配的数组元素

如果要在服务器上筛选数组内容,聚合框架是一种方法

db.collection.aggregate([
    {
        "$match": {
            "m._t": {
                "$in": ["type1", "type2"]
            }
        }
    },
    {
        "$unwind": "$m"
    },
    {
        "$match": {
            "m._t": {
                "$in": ["type1", "type2"]
            }
        }
    },
    {
        "$group": {
            "_id": "$_id",
            "m": {
                "$push": "$m"
            }
        }
    }
])
/* 0 */
{
    "result" : [ 
        {
            "_id" : 2,
            "m" : [ 
                {
                    "_id" : 21,
                    "_t" : "type1"
                }
            ]
        }, 
        {
            "_id" : 1,
            "m" : [ 
                {
                    "_id" : 11,
                    "_t" : "type1"
                }, 
                {
                    "_id" : 12,
                    "_t" : "type2"
                }
            ]
        }
    ],
    "ok" : 1
}