seasons.json
{
"_id" : "unique_1",
"spring" : [{
"fruit" : "mango",
"person_id" : [101.0, 102.0, 103.0, 104.0]
}, {
"fruit" : "banana",
"person_id" : [151.0, 152.0, 153.0, 154.0]
}],
"summer" : [{
"fruit" : "mango",
"person_id" : [201.0, 202.0, 203.0, 204.0]
}, {
"fruit" : "banana",
"person_id" : [251.0, 252.0, 253.0, 254.0]
}],
"fall" : [{
"fruit" : "mango",
"person_id" : [301.0, 302.0, 303.0, 304.0]
}, {
"fruit" : "banana",
"person_id" : [351.0, 352.0, 353.0, 354.0]
}],
"winter" : [{
"fruit" : "mango",
"person_id" : [401.0, 402.0, 403.0]
}, {
"fruit" : "banana",
"person_id" : [451.0, 452.0, 453.0]
}]
}
/* 2 */
{
"_id" : "unique_2",
"spring" : [{
"fruit" : "banana",
"person_id" : [151.0, 152.0, 153.0, 154.0]
}],
"summer" : [{
"fruit" : "mango",
"person_id" : [201.0, 202.0, 203.0, 204.0]
}, {
"fruit" : "banana",
"person_id" : [251.0, 252.0, 253.0, 254.0]
}],
"fall" : [{
"fruit" : "banana",
"person_id" : [351.0, 352.0, 353.0, 354.0]
}],
"winter" : [{
"fruit" : "mango",
"person_id" : [401.0, 402.0, 403.0]
}, {
"fruit" : "banana",
"person_id" : [451.0, 452.0, 453.0]
}]
}
以上JSON记录显示哪个人吃了芒果哪个人吃过香蕉。
这是我想要找到的: 当我事先知道记录的_id(主键)或记录发现之前 -
1)所有person_id范围从101到350,其中person_id是唯一的 2)person_id只吃芒果 3)在记录中吃芒果或香蕉的人的总人数。
答案 0 :(得分:3)
使用这样的模式,运行像您需要的那样的查询将非常困难。考虑改变模式,使得每个子文档都有一个主键,例如seasons
,它可以有四个不同的数组元素,即春天,夏天,冬天和秋天。将架构更改为:
/* 1 */
{
"_id" : "unique_1",
"seasons" : [
{
"name" : "spring",
"fruits" : [
{
"name" : "mango",
"person_id" : [
101,
102,
103,
104
]
},
{
"name" : "banana",
"person_id" : [
151,
152,
153,
154
]
}
]
},
{
"name" : "summer",
"fruits" : [
{
"name" : "mango",
"person_id" : [
201,
202,
203,
204
]
},
{
"name" : "banana",
"person_id" : [
251,
252,
253,
254
]
}
]
},
{
"name" : "fall",
"fruits" : [
{
"name" : "mango",
"person_id" : [
301,
302,
303,
304
]
},
{
"name" : "banana",
"person_id" : [
351,
352,
353,
354
]
}
]
},
{
"name" : "winter",
"fruits" : [
{
"name" : "mango",
"person_id" : [
401,
402,
403
]
},
{
"name" : "banana",
"person_id" : [
451,
452,
453
]
}
]
}
]
}
使用此模式,运行以下聚合查询变得更加容易:
1)所有person_id范围从101到350,其中person_id是唯一的
var pipeline1 = [
{ "$match": { "_id": "unique_1" },
{ "$unwind": "$seasons" },
{ "$unwind": "$seasons.fruits" },
{ "$unwind": "$seasons.fruits.person_id" },
{
"$match": {
"seasons.fruits.person_id": {
"$gte": 101,
"$lte": 350
}
}
},
{
"$group": {
"_id": 0,
"person_ids": {
"$addToSet": "$seasons.fruits.person_id"
}
}
},
{
"$project": {
"_id": 0,
"person_ids": 1
}
}
];
db.season.aggregate(pipeline1);
<强>输出强>:
/* 1 */
{
"result" : [
{
"person_ids" : [
304,
253,
201,
251,
301,
203,
252,
204,
152,
102,
202,
154,
254,
101,
302,
153,
104,
103,
303,
151
]
}
],
"ok" : 1
}
2)person_id只吃芒果
var pipeline2 = [
{ "$match": { "_id": "unique_1" },
{ "$unwind": "$seasons" },
{ "$unwind": "$seasons.fruits" },
{ "$unwind": "$seasons.fruits.person_id" },
{
"$match": {
"seasons.fruits.name": "mango"
}
},
{
"$group": {
"_id": 0,
"person_ids": {
"$addToSet": "$seasons.fruits.person_id"
}
}
},
{
"$project": {
"_id": 0,
"person_ids": 1
}
}
];
db.season.aggregate(pipeline2);
<强>输出强>:
/* 1 */
{
"result" : [
{
"person_ids" : [
402.0000000000000000,
304.0000000000000000,
303.0000000000000000,
302.0000000000000000,
301.0000000000000000,
204.0000000000000000,
202.0000000000000000,
201.0000000000000000,
203.0000000000000000,
104.0000000000000000,
102.0000000000000000,
103.0000000000000000,
403.0000000000000000,
401.0000000000000000,
101.0000000000000000
]
}
],
"ok" : 1
}
3)在记录中吃芒果或香蕉的人的总人数。
var pipeline3 = [
{ "$match": { "_id": "unique_1" },
{ "$unwind": "$seasons" },
{ "$unwind": "$seasons.fruits" },
{ "$unwind": "$seasons.fruits.person_id" },
{
"$match": {
"seasons.fruits.name": {
"$in": ["mango", "banana"]
}
}
},
{
"$group": {
"_id": "$_id",
"count": {
"$sum": 1
}
}
},
{
"$project": {
"_id": 0,
"count": 1
}
}
];
db.season.aggregate(pipeline3);
<强>输出强>:
/* 1 */
{
"result" : [
{
"count" : 30
}
],
"ok" : 1
}