空数组阻止文档出现在查询中 [英] Empty array prevents document to appear in query

查看:73
本文介绍了空数组阻止文档出现在查询中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的文档有几个字段,尤其是有一个名为 attrs 的字段,它是一个数组.我正在使用聚合管道.

I have documents that have a few fields and in particular the have a field called attrs that is an array. I am using the aggregation pipeline.

在我的查询中,如果其中包含任何元素,我会对 attrs (属性)字段感兴趣.否则我仍然想要得到结果.在这种情况下,我在文档的 type 字段之后.

In my query I am interested in the attrs (attributes) field if there are any elements in it. Otherwise I still want to get the result. In this case I am after the field type of the document.

问题在于,如果文档的 attrs 字段中不包含任何元素,它将被过滤掉,而我不会得到其 _id.type 字段,这是我真正想要的查询.

The problem is that if a document does not contain any element in the attrs field it will be filtered away and I won't get its _id.type field, which is what I really want from this query.

{
    aggregate: "entities",
    pipeline: [
        {
            $match: {
                _id.servicePath: {
                    $in: [
                        /^/.*/,
                        null
                    ]
                }
            }
        },
        {
            $project: {
                _id: 1,
                "attrs.name": 1,
                "attrs.type": 1
            }
        },
        {
            $unwind: "$attrs"
        },
        {
            $group: {
                _id: "$_id.type",
                attrs: {
                    $addToSet: "$attrs"
                }
            }
        },
        {
            $sort: {
                _id: 1
            }
        }
    ]
}

所以问题是:如何获得一个包含所有文档类型的结果,而不管它们是否具有 attrs ,但包括属性(如果它们具有属性的话)?

So the question is: how can I get a result containing all documents types regardless of their having attrs, but including the attributes in case they have them?

我希望这是有道理的.

推荐答案

您可以使用

You can use the $cond operator in a $project stage to replace the empty attr array with one that contains a placeholder like null that can be used as a marker to indicate that this doc doesn't contain any attr elements.

因此,您需要在$unwind之前的位置插入一个额外的$project阶段:

So you'd insert an additional $project stage like this right before the $unwind:

    {
        $project: {
            attrs: {$cond: {
               if: {$eq: ['$attrs', [] ]},
               then: [null],
               else: '$attrs'
           }}
        }
    },

唯一的警告是,对于包含至少一个文档且没有任何attrs元素的组,您将在最终的attrs数组中以null值结尾,因此您需要忽略这些客户端-一侧.

The only caveat is that you'll end up with a null value in the final attrs array for those groups that contain at least one doc without any attrs elements, so you need to ignore those client-side.

示例

该示例使用一个更改的$match阶段,因为示例中的那个无效.

The example uses an altered $match stage because the one in your example isn't valid.

输入文档

[
  {_id: {type: 1, id: 2}, attrs: []},
  {_id: {type: 2, id: 1}, attrs: []},
  {_id: {type: 2, id: 2}, attrs: [{name: 'john', type: 22}, {name: 'bob', type: 44}]}
]

输出

{
    "result" : [ 
        {
            "_id" : 1,
            "attrs" : [ 
                null
            ]
        }, 
        {
            "_id" : 2,
            "attrs" : [ 
                {
                    "name" : "bob",
                    "type" : 44
                }, 
                {
                    "name" : "john",
                    "type" : 22
                }, 
                null
            ]
        }
    ],
    "ok" : 1
}

聚合命令

db.test.aggregate([
    {
        $match: {
            '_id.servicePath': {
                $in: [
                    null
                ]
            }
        }
    },
    {
        $project: {
            _id: 1,
            "attrs.name": 1,
            "attrs.type": 1
        }
    },
    {
        $project: {
            attrs: {$cond: {
               if: {$eq: ['$attrs', [] ]},
               then: [null],
               else: '$attrs'
           }}
        }
    },
    {
        $unwind: "$attrs"
    },
    {
        $group: {
            _id: "$_id.type",
            attrs: {
                $addToSet: "$attrs"
            }
        }
    },
    {
        $sort: {
            _id: 1
        }
    }
])

这篇关于空数组阻止文档出现在查询中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆