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
用于此目的的参考文献,但我并不特别相信,因为尽管它确实存在,但它并非用于此目的,因此没有正式记录。