Mongo - 数组查询,仅查找所有元素匹配的位置

use*_*882 6 php arrays mongodb

我正在尝试创建一个mongo查询,该查询将返回所有数组都将特定元素设置为false的结果.

一个示例数据记录: -

images: [
    {
        id: ObjectId("516bef7fc05e877b31000000"),
        primary: true
    },
    {
        id: ObjectId("516bef2ac05e879622000000"),
        primary: false
    },
    {
        id: ObjectId("516beeb7c05e879e2a000000"),
        primary: false
    }
],
name: "test",
etc: "etc"
Run Code Online (Sandbox Code Playgroud)

我只希望找到所有主要字段都设置为false的文档,但通常情况下(不使用查询选择器或elemMatch)mongo将返回此文档,因为至少有一个数组元素匹配.

如何使mongo只返回与我的搜索参数匹配的文档?

非常感谢.

Der*_*ick 6

你可以很容易地使用聚合框架来做到这一点:

db.so.aggregate( [
    { $unwind: "$images" },
    { $group: { 
        _id: '$_id', 
        all: { $sum: 1 },
        all_primary: { $sum: { $cond: [ { $eq: [ '$images.primary', true ] }, 1, 0 ] } },
        images: { $push: '$images' },
        name: { $first: '$name' },
        etc: { $first: '$etc' },
    } },
    { $project: {
        _id: 1,
        images: 1,
        name: 1,
        etc: 1,
        same: { $cond: [ { $eq: [ '$all', '$all_primary' ] }, 1, 0 ] }
    } },
    { $match: { 'same' : 1 } } 
] );
Run Code Online (Sandbox Code Playgroud)

以此作为输入:

{
    "_id" : ObjectId("5203730bf8eaa52a846ebc3e"),
    "images" : [
        {
            "id" : ObjectId("516bef7fc05e877b31000000"),
            "primary" : true
        },
        {
            "id" : ObjectId("516bef2ac05e879622010000"),
            "primary" : true
        },
        {
            "id" : ObjectId("516beeb7c05e879e2a000010"),
            "primary" : true
        }
    ],
    "name" : "Derick",
    "Etc" : true
}
{
    "_id" : ObjectId("52037315f8eaa52a846ebc3f"),
    "images" : [
        {
            "id" : ObjectId("516bef7fc05e877b31000000"),
            "primary" : true
        },
        {
            "id" : ObjectId("516bef2ac05e879622010000"),
            "primary" : true
        },
        {
            "id" : ObjectId("516beeb7c05e879e2a000020"),
            "primary" : false
        }
    ],
    "name" : "James",
    "Etc" : true
}
{
    "_id" : ObjectId("520373621a78238235b6ffbf"),
    "images" : [
        {
            "id" : ObjectId("516bef7fc05e877b31000000"),
            "primary" : true
        },
        {
            "id" : ObjectId("516bef2ac05e879622010000"),
            "primary" : true
        },
        {
            "id" : ObjectId("516beeb7c05e879e2a000020"),
            "primary" : false
        }
    ],
    "name" : "James",
    "etc" : true
}
{
    "_id" : ObjectId("5203736b1a78238235b6ffc0"),
    "images" : [
        {
            "id" : ObjectId("516bef7fc05e877b31000000"),
            "primary" : true
        },
        {
            "id" : ObjectId("516bef2ac05e879622010000"),
            "primary" : true
        },
        {
            "id" : ObjectId("516beeb7c05e879e2a000020"),
            "primary" : true
        }
    ],
    "name" : "James",
    "etc" : true
}
Run Code Online (Sandbox Code Playgroud)

这输出:

{
    "result" : [
        {
            "_id" : ObjectId("5203736b1a78238235b6ffc0"),
            "images" : [
                {
                    "id" : ObjectId("516bef7fc05e877b31000000"),
                    "primary" : true
                },
                {
                    "id" : ObjectId("516bef2ac05e879622010000"),
                    "primary" : true
                },
                {
                    "id" : ObjectId("516beeb7c05e879e2a000020"),
                    "primary" : true
                }
            ],
            "name" : "James",
            "etc" : true,
            "same" : 1
        },
        {
            "_id" : ObjectId("5203730bf8eaa52a846ebc3e"),
            "images" : [
                {
                    "id" : ObjectId("516bef7fc05e877b31000000"),
                    "primary" : true
                },
                {
                    "id" : ObjectId("516bef2ac05e879622010000"),
                    "primary" : true
                },
                {
                    "id" : ObjectId("516beeb7c05e879e2a000010"),
                    "primary" : true
                }
            ],
            "name" : "Derick",
            "etc" : null,
            "same" : 1
        }
    ],
    "ok" : 1
}
Run Code Online (Sandbox Code Playgroud)