使用MongoDB将多个阵列聚合为一个巨大的阵列 [英] Aggregate multiple arrays into one huge array with MongoDB

查看:45
本文介绍了使用MongoDB将多个阵列聚合为一个巨大的阵列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收集了包含以下文件的文件:

I got a collection with documents such as those:

{
    "_id": 0,
    "pictures": [
        {
            "path": "/path/to/first/picture.jpg",
            "web": "true"
        },
        {
            "path": "/path/to/second/picture.jpg",
            "web": "true",
        }
    ],
    "logos": [
        {
            "path": "/path/to/first/logo.jpg",
            "web": "true"
        },
        {
            "path": "/path/to/second/logo.jpg",
            "web": "false",
        }
    ]
}
{
    "_id": 1,
    "pictures": [
        {
            "path": "/a/bit/weird/path/to/picture.jpg",
            "web": "false"
        },
        {
            "path": "/another/weird/path/to/picture.jpg",
            "web": "false",
        }
    ],
    "logos": [
        {
            "path": "/path/to/another/logo.jpg",
            "web": "false"
        },
        {
            "path": "/a/last/path/to/logo.jpg",
            "web": "true",
        }
    ]
}

我想要得到的结果是具有以下条件的这一点.

What I'm trying to get as result is this one with the conditions below.

{ 
    "web_images": [
        {
            "path": "/path/to/first/picture.jpg",
            "web": "true"
        },
        {
            "path": "/path/to/second/picture.jpg",
            "web": "true",
        },
        {
            "path": "/path/to/first/logo.jpg",
            "web": "true"
        },
        {
            "path": "/a/last/path/to/logo.jpg",
            "web": "true",
        }
    ]
}

唯一的实际条件是获取所有路径,这些路径的字段"web"处的字符串设置为true. (我知道也可能是布尔值,但是在这种情况下没关系) 主要问题是将数组徽标"和图片"合并为一个数组. 我使用"$ unwind"阅读了一些解决方案.但是在那种情况下,他们试图连接一个数组.

The only real condition on that is to get all paths, that have the string at the field "web" set on true. (I know it could also be bool, but it doesn't matter in this case) The main problem is to concat the arrays "logos" and "pictures" into one array. I read some solutions using "$unwind". But in those cases, they are trying to concatenate one array.

这对我有用,但是在我的实际情况下,我得到了包含这些对象的五个不同的数组.而且它们必须将结果全部放在一个数组中.


到目前为止,我的解决方案如下(但不起作用):

This worked for me, but in my real case I got five different arrays containing those objects. And they have to result all in one array.


My solution so far looks as following (but doesn't work):

db.products.aggregate( [
    { $unwind: "$pictures" },
    { $unwind: "$logos" },
    { $group: { _id: null, pics: { $push: { $or: ["$pictures", "$logos"] } } } }
    { $project: { _id: 0, pictures: "$pics" } }
] );

如您所见,仍然缺少"web"标志上的条件检查.同样,输出绝对不会带来任何结果.甚至没有错误消息.


编辑

As you can see there is still the condition checking on the "web"-flag missing. Also the output brings absolutely nothing. Not even an error message.


EDIT

我忘记了这个问题的重要细节.

I forgot an important detail on this question.

正如我在上部分中所述,每个文档中有五个可以出现的不同数组.每个文档中可能没有任何一个.因此它也可能像这样:

As I described in the upper part there are five different arrays that can appear in each document. It is also possible that there aren't any of them in each document. So it can also look like this:

{
    "_id": 1,
    "pictures": [
        {
            "path": "/a/bit/weird/path/to/picture.jpg",
            "web": "false"
        },
        {
            "path": "/another/weird/path/to/picture.jpg",
            "web": "false",
        }
    ]
}

这可能是我解决的问题之间的区别,我的问题被标记为重复.正如@Styvane告诉我要做的那样,它只给了我成吨的文件,例如:

That could be the difference between my problem the solved one, which my was marked as duplicate to. As @Styvane told me to do it gave me just tons of documents such as this:

{
    "_id" : ObjectId("57f5026aaf39013d0c9186af"),
    "web_images": null
}

由于那些缺少某些数组的文档,我可能会收到此错误.

It is possible that I get this error because of those documents which have some arrays missing.

推荐答案

您可以使用 $setUnion / $concatArrays 运算符来连接和过滤文档.另外,您还需要使用 $ifNull 运算符来替换缺少的空数组的字段.

You can use the $filter and the $setUnion/$concatArrays operators to concatenate and filter your documents. Also you need to use the $ifNull operator to replace the missing field with empty array.

db.collection.aggregate([
    { "$project": { 
        "web_images": { 
            "$filter": { 
                "input": { 
                    "$setUnion": [ 
                        { "$ifNull": [ "$pictures", [] ] },
                        { "$ifNull": [ "$logos", [] ] }
                    ]
                }, 
                "as": "p", 
                "cond": { "$eq": [ "$$p.web", "true" ] } 
            } 
        } 
    }},
    { "$match": { "web_images.0": { "$exists": true } } }
])

这篇关于使用MongoDB将多个阵列聚合为一个巨大的阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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