Mongodb-使用聚合框架将多个字段分组
我有一些文件Mongodb-使用聚合框架将多个字段分组,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一些文件 {name:'apple',type:'fruit',color:'red'} {名称:“香蕉”,类型:“水果”,颜色:“黄色”} {名称:“橙色”,类型:“水果”,颜色:“橙色”} {名称:“茄子”,类型:“蔬菜”,颜色:“紫色”} {名称:'brocoli',类型:'vege',颜色:'green'} {名称:'rose',类型:'flower',颜色:'red'} {名称:'cauli',类型:'vege',颜色:'white'} {名称:'potato',类型:'vege'
{name:'apple',type:'fruit',color:'red'}
{名称:“香蕉”,类型:“水果”,颜色:“黄色”}
{名称:“橙色”,类型:“水果”,颜色:“橙色”}
{名称:“茄子”,类型:“蔬菜”,颜色:“紫色”}
{名称:'brocoli',类型:'vege',颜色:'green'}
{名称:'rose',类型:'flower',颜色:'red'}
{名称:'cauli',类型:'vege',颜色:'white'}
{名称:'potato',类型:'vege',颜色:'brown'}
{名称:“洋葱”,类型:“蔬菜”,颜色:“白色”}
{名称:“草莓”,类型:“水果”,颜色:“红色”}
{名称:“腰果”,类型:“坚果”,颜色:''
{名称:'almond',类型:'nut',颜色:'''
{名称:'lemon',类型:'vege',颜色:'yellow'}
{名称:“番茄”,类型:“蔬菜”,颜色:“红色”}
{名称:“番茄”,类型:“水果”,颜色:“红色”}
{名称:'fig',类型:'FROUT',颜色:'pink'}
{名称:'油桃',类型:'水果',颜色:'粉红'}
我想把它们分成下面这样的字母表
{
_id:'a',
名称:[“苹果”、“杏仁”],
类型:[],
颜色:[]
}
{
_id:'b',
名称:[“香蕉”、“花椰菜”],
类型:[],
颜色:[“棕色”]
}
...
{
_id:'f',
名称:['fig'],
类型:[“水果”、“花”],
颜色:['']
}
...
{
_id:'n',
名称:[‘油桃’],
类型:[“螺母”],
颜色:['']
}
...
{
_id:'p',
名称:[“土豆”],
类型:[''],
颜色:[“粉色”、“紫色”]
}
...
结果可以保存到另一个集合中。因此,我可以在新创建的集合中发出一个查询:find({u id:'a'})
返回名称、类型和颜色,以字母“a”开头
我考虑过使用$group
$group:{
_id:$substr:['$name',0,1],
名称:{$addToSet:'$name'},
}
然后是另一个命令
$group:{
_id:$substr:['$type',0,1],
名称:{$addToSet:'$type'},
}
及
$group:{
_id:$substr:['$color',0,1],
名称:{$addToSet:'$color'},
}
但我被困在如何将这三者统一起来,保存到一个新的集合中。或者聚合框架不适合这种数据摘要
在一个现实世界的例子中,例如一个电子商务网站,首页显示如下内容:“目前我们在111
品牌的231
类别下有135636
产品”。当然,这些数字应该缓存在某个地方(内存或其他集合中),因为每次运行$group
都需要大量资源?对于这些情况,最佳的模式/设计是什么
抱歉,我的问题有点“混乱”。使用聚合时,您应该使用一些复杂的聚合查询。首先使用
substr
找出所有name
首字母,然后创建所有name,使用组
键入和颜色
数组使用检查给定名称是否以开头用于删除重复的空参数,最后是用于在新集合中写入文档
检查此聚合查询:
db.collection.aggregate({
"$project": {
"firstName": {
"$substr": ["$name", 0, 1]
},
"name": 1,
"type": 1,
"color": 1
}
}, {
"$group": {
"_id": null,
"allName": {
"$push": "$name"
},
"allType": {
"$push": "$type"
},
"allColor": {
"$push": "$color"
},
"allfirstName": {
"$push": "$firstName"
}
}
}, {
"$unwind": "$allfirstName"
}, {
"$group": {
"_id": "$allfirstName",
"allType": {
"$first": "$allType"
},
"allName": {
"$first": "$allName"
},
"allColor": {
"$first": "$allColor"
}
}
}, {
"$project": {
"type": {
"$setDifference": [{
"$map": {
"input": "$allType",
"as": "type",
"in": {
"$cond": {
"if": {
"$eq": [{
"$substr": ["$$type", 0, 1]
}, "$_id"]
},
"then": "$$type",
"else": ""
}
}
}
},
[""]
]
},
"color": {
"$setDifference": [{
"$map": {
"input": "$allColor",
"as": "color",
"in": {
"$cond": {
"if": {
"$eq": [{
"$substr": ["$$color", 0, 1]
}, "$_id"]
},
"then": "$$color",
"else": ""
}
}
}
},
[""]
]
},
"name": {
"$setDifference": [{
"$map": {
"input": "$allName",
"as": "name",
"in": {
"$cond": {
"if": {
"$eq": [{
"$substr": ["$$name", 0, 1]
}, "$_id"]
},
"then": "$$name",
"else": ""
}
}
}
},
[""]
]
}
}
}, {
"$sort": {
"_id": 1
}
}, {
"$out": "newCollection"
})
因为这里有多个数组,关键是将它们“合并”到一个数组中,以便进行最简单的处理 聚合框架的操作符在这里工作得很好,还可以转换元素,以便从数据中的每个单词中获得“第一个字母”:
db.alpha.aggregate([
{“$project”:{
“名单”:{
“$map”:{
“输入”:[“A”、“B”、“C”],
“as”:“el”,
“在”:{
“$cond”:[
{“$eq”:[“$$el”,“A”]},
{
“type”:{“$literal”:“name”},
“值”:“$name”,
“alpha”:{“$substr”:[“$name”,0,1]}
},
{“$cond”:[
{“$eq”:[“$$el”,“B”]},
{
“类型”:{“$literal”:“类型”},
“值”:“$type”,
“alpha”:{“$substr”:[“$type”,0,1]}
},
{
“type”:{“$literal”:“color”},
“值”:“$color”,
“alpha”:{“$substr”:[“$color”,0,1]}
}
]}
]
}
}
}
}},
{“$unwind”:“$list”},
{“$match”:{“list.alpha”:{“$ne”:“}}},
{“$组”:{
“_id”:“$list.alpha”,
“名单”:{
$addToSet:“$list”
}
}},
{“$project”:{
“姓名”:{
“$setDifference”:[
{“$map”:{
“输入”:“$list”,
“as”:“el”,
“在”:{
“$cond”:[
{“$eq”:[“$$el.type”,“name”]},
“$$el.value”,
假的
]
}
}},
[错误]
]
},
“类型”:{
“$setDifference”:[
{“$map”:{
“输入”:“$list”,
“as”:“el”,
“在”:{
“$cond”:[
{“$eq”:[“$$el.type”,“type”]},
“$$el.value”,
假的
]
}
}},
[错误]
]
},
“颜色”:{
“$setDifference”:[
{“$map”:{
“输入”:“$list”,
“as”:“el”,
“在”:{
“$cond”:[
{“$eq”:[“$$el.type”,“color”]},
“$$el.value”,
假的
]
}
}},
[错误]
]
}
}},
{“$sort”:{“\u id”:1}
])
如果您在“阶段”中查看数据,那么在转换过程中发生的事情就很有意义了
第一阶段将所有字段“映射”到每个文档的单个数组中,因此所有文档现在看起来如下所示:
{
“_id”:ObjectId(“55df0652c9064ef625d7f36e”),
“名单”:[
{
“类型”:“名称”,
“价值”:“油桃”,
“alpha”:“n”
},
{
“类型”:“类型”,
“价值”:“水果”,
“阿尔法”: