使用公共数据合并内部数组


db.test.aggregate([
    { "$unwind": "$Data" },
    { "$sort" : { "Data.cost" : -1 } },
    { "$group":{  
        "_id":"$Data.name",
        "Data":{ "$push": "$Data" }
    }}
])

我驳回了上述质疑。它给我的结果如下:

{
    "result":[{
        "_id" : "abc"
        "Data" : [
            {
                "uid" : "1...A",
                "name" : "abc",
                "city" : "Paris",
                "description" : {
                    "things" : [
                        {
                            "fruit" : {
                                "fruit_name" : "apple",
                                "fruit_rate" : "4 USD"
                            },
                            "flower" : {
                                "flower_name" : "rose",
                                "flower_rate" : "2 USD"
                            }
                        }
                    ]
                },
                "cost" : "6 USD"
            },
            {
                "uid" : "1...B",
                "name" : "abc",
                "city" : "Paris",
                "description" : {
                    "things" : [
                        {
                            "fruit" : {
                                "fruit_name" : "cherry",
                                "fruit_rate" : "3 USD"
                            },
                            "flower" : {
                                "flower_name" : "orchid",
                                "flower_rate" : "2 USD"
                            }
                        }
                    ]
                }, 
                "cost" : "5 USD"
            }
        ]
    }]
}

但我不想要这样的结果。如果"name">相同,我想合并两个数据的的"description"

{
    "result":[{
        "_id" : "abc"
        "Data" : [
            {
                "uid" : "1...A",
                "name" : "abc",
                "city" : "Paris",
                "description" : {
                    "things" : [
                        {
                            "fruit" : {
                                "fruit_name" : "apple",
                                "fruit_rate" : "4 USD"
                            },
                            "flower" : {
                                "flower_name" : "rose",
                                "flower_rate" : "2 USD"
                            }
                        }
                    ]
                },
                "description" : {
                    "things" : [
                        {
                            "fruit" : {
                                "fruit_name" : "cherry",
                                "fruit_rate" : "3 USD"
                            },
                            "flower" : {
                                "flower_name" : "orchid",
                                "flower_rate" : "2 USD"
                            }
                        }
                    ]
                }, 
                "cost" : "6 USD"   
            }
        ]
    }]
}

有可能得到这样的结果吗?我在查询中要做哪些更改

谢谢。

构建所需结果的方式根本不可能。这样做的原因是,您基本上打破了哈希表或字典/关联数组(无论哪个术语更适合您(背后的原则,因为您不能拥有多个同名的键值。

如果您想要多个同名的键,那么这些键必须包含在一个数组中,这与您的结构非常相似,也与您的结果非常相似。这个结果除了对数组元素进行排序,然后将它们重新分组到一个数组中之外,什么也没做。

因此,在这里给你一点空间,你只需复制和粘贴即可表示你想要的结果,并且你实际上想要某种形式的合并内部元素,你总是可以这样做:

db.test.aggregate([
    { "$unwind": "$Data" },
    { "$unwind": "$Data.description.things" },
    { "$group": {
        "_id": "$Data.name",
        "city": { "$first": "$Data.city" },
        "things": { "$addToSet": "$Data.description.things" }
    }}
])

产生一个结果:

{
    "_id" : "abc",
    "city" : "Paris",
    "things" : [
        {
            "fruit" : {
                "fruit_name" : "cherry",
                "fruit_rate" : "3 USD"
             },
             "flower" : {
                 "flower_name" : "orchid",
                 "flower_rate" : "2 USD"
             }
        },
        {
             "fruit" : {
                 "fruit_name" : "apple",
                 "fruit_rate" : "4 USD"
             },
             "flower" : {
                 "flower_name" : "rose",
                 "flower_rate" : "2 USD"
             }
        }
    ]
}

因此,内部的"事物"现在被"推"到一个奇异数组中,同时对一个公共元素进行分组并添加一些额外的字段。

如果你真的想要更"合并">的东西,甚至可能避免删除重复的"集合"项目,那么你可以用这样的语句来进一步重塑:

db.test.aggregate([
    { "$unwind": "$Data" },
    { "$unwind": "$Data.description.things" },
    { "$project": {
         "name": "$Data.name",
         "city": "$Data.city",
         "things": "$Data.description.things",
         "type": { "$literal": [ "flower", "fruit" ] }
    }},
    { "$unwind": "$type" },
    { "$group": {
        "_id": "$name",
        "city": { "$first": "$city" },
        "things": { "$push": { "$cond": [
            { "$eq": [ "$type", "flower" ] },
            { 
                "type": "$type", 
                "name": "$things.flower.flower_name", 
                "rate": "$things.flower.flower_rate"
            },
            { 
                "type": "$type", 
                "name": "$things.fruit.fruit_name", 
                "rate": "$things.fruit.fruit_rate"
            },
        ]}}
    }}
 ])

这给出了一个结果:

{
    "_id" : "abc",
    "city" : "Paris",
    "things" : [
        {
            "type" : "flower",
            "name" : "rose",
            "rate" : "2 USD"
        },
        {
            "type" : "fruit",
            "name" : "apple",
            "rate" : "4 USD"
        },
        {
            "type" : "flower",
            "name" : "orchid",
            "rate" : "2 USD"
        },
        {
            "type" : "fruit",
            "name" : "cherry",
            "rate" : "3 USD"
        }
    ]
}

这甚至可能表明最初如何更好地构建原始数据。当然,如果你想做"找到‘樱桃’、‘花’或‘水果’的总值">或任何类型的事情,你需要像这样重新塑造。

因此,你构建结果的方式是不可能的,你违反了前面提到的规则。在我介绍的表格中,有几种方法可以做到这一点。

p。S:我有意远离您的$sort表示,就好像它在您最初的示例中"有点"对您有效一样,不要指望它在更广泛的示例中有效,因为您的值是字符串而不是数字。简而言之,这意味着"10 USD"实际上小于"4 USD",因为这就是字符串在词汇上的比较方式。即:4大于1,这是进行比较的顺序。

因此,通过拆分字段并使用数字类型来更改这些字段,如:

        {
            "type" : "fruit",
            "name" : "cherry",
            "rate" : 3,
            "currency": "USD"
        }

如果需要的话,你甚至可以过滤"货币"。

p。P.S$literal运算符是适用于MongoDB 2.6及更高版本的构造。在以前的版本中,如果该操作员不可用,您可以改为这样编码:

         "type": { "$cond": [ 1, [ "flower", "fruit" ], 0 ] }

它的作用与$cond返回的true值(甚至false值(被"字面上"声明的作用相同,所以你放在那里的东西实际上会产生。在这种情况下,这是一种向投影添加"数组"的方式,这是为了匹配"类型"所需要的。

您可能会在网上找到使用$const用于此目的的参考文献,但我并不特别相信,因为尽管它确实存在,但它并非用于此目的,因此没有正式记录

最新更新