Javascript Mongo在单个字段上设置交集,该字段是二维数组
我在mongo有以下结构的文件。我想得到一个父母中孩子的所有常见日期Javascript Mongo在单个字段上设置交集,该字段是二维数组,javascript,mongodb,set,mongodb-query,aggregation-framework,Javascript,Mongodb,Set,Mongodb Query,Aggregation Framework,我在mongo有以下结构的文件。我想得到一个父母中孩子的所有常见日期 {“父”:1,“子”:“a”,“日期”:“2016-02-01”}, {“父”:1,“子”:“a”,“日期”:“2016-02-02”}, {“父”:1,“子”:“a”,“日期”:“2016-02-03”}, {“父”:1,“子”:“b”,“日期”:“2016-02-01”}, {“父”:1,“子”:“b”,“日期”:“2016-02-03”}, {“父”:2,“子”:“a”,“日期”:“2016-02-02”}, {“父母”
{“父”:1,“子”:“a”,“日期”:“2016-02-01”},
{“父”:1,“子”:“a”,“日期”:“2016-02-02”},
{“父”:1,“子”:“a”,“日期”:“2016-02-03”},
{“父”:1,“子”:“b”,“日期”:“2016-02-01”},
{“父”:1,“子”:“b”,“日期”:“2016-02-03”},
{“父”:2,“子”:“a”,“日期”:“2016-02-02”},
{“父母”:2,“子女”:“a”,“日期”:“2016-02-03”},
{“父”:2,“子”:“b”,“日期”:“2016-02-01”},
{“父”:2,“子”:“b”,“日期”:“2016-02-02”}
为此,我将聚合框架与以下管道一起使用,以获得一个日期数组数组
{
$group:{
_身份证:{
父项:“$parent”,
儿童:$child
},
日期:{
$push:“$date”
}
}
}, {
$group:{
_id:“$\u id.parent”,
日期:{
$push:“$dates”
}
}
}
输出结果如下:
[
{
“_id”:1,
“日期”:[
[
"2016-02-01",
"2016-02-03"
],
[
"2016-02-01",
"2016-02-02",
"2016-02-03"
]
]
},
{
“_id”:2,
“日期”:[
[
"2016-02-01",
"2016-02-02"
],
[
"2016-02-02",
"2016-02-03"
]
]
}
]
现在,我想获得每个文档的2d数组中的所有常见日期,并尝试使用$setcrossion
添加$projection
阶段。但据我所知,$setcrossion
需要一个定义良好的字段或数组数组-使用$setcrossion:“$dates”
无法按预期工作
感谢您的帮助
附加信息:子类型的数量是可变的
预期产出:
[
{
"_id" : 1.0000000000000000,
"dates" : [
"2016-02-01",
"2016-02-03"
]
},
{
"_id" : 2.0000000000000000,
"dates" : [
"2016-02-02"
]
}
]
使用MongoDB 3.2,您可以获得二维的每个元素,并将其提供给:
db.collection.aggregate([
{“$组”:{
“_id”:{
“父项”:“$parent”,
“child”:“$child”
},
“日期”:{“$push”:“$date”}
}},
{“$组”:{
“\u id”:“$\u id.parent”,
“日期”:{“$push”:“$dates”}
}},
{“$project”:{
“日期”:{
“$setcrossion”:[
{“$arrayElemAt”:[“$dates”,0]},
{“$arrayElemAt”:[“$dates”,1]}
]
}
}}
])
但事实上,您所看到的特定问题可以用更简单的方式解决。基本上,你需要做的就是在父对象上计算每个日期发生的子对象。多于一个表示有两个或多个孩子共享日期:
db.collection.aggregate([
{“$组”:{
“_id”:{
“父项”:“$parent”,
“日期”:“$date”
},
“计数”:{“$sum”:1}
}},
{“$match”:{“count”:{“$gt”:1}}},
{“$组”:{
“\u id”:“$\u id.parent”,
“日期:{“$push”:“$\u id.date”}
}}
])
因此没有理由比较数组,因为一个简单的分组元素计数告诉您“集合交集”是什么
同样的原则也适用于引入聚合框架的每个MongoDB版本
两者都会产生相同的结果:
{u id:1,“日期”:[“2016-02-03”,“2016-02-01”]}
{“_id”:2,“日期”:[“2016-02-02”]}
还要注意的是,“集合”不被认为是有序的,从
$group
发出的键的顺序也不被认为是有序的。这里可以做的是计算父级的子级数量,并计算父级的每个子级的日期数量
然后获取所有日期,其中日期数等于父级的子级数,这将给出预期的输出
这是我尝试过的,但可能有更好的解决方案
db.coll.aggregate([
{
$group: {
_id: {
parent: "$parent",
child: "$child"
},
dates: {
$push: "$date"
}
}
},
{
$group: {
_id: "$_id.parent",
total_children: {$sum : 1},
dates: {
$push: "$dates"
}
}
},
{
$unwind : "$dates"
},
{
$unwind : "$dates"
},
{
$group : {
_id : {
parent : "$_id",
dates : "$dates"
},
total_children : {$first : "$total_children"},
total_dates : {$sum : 1}
}
},
{
$project : {
_id : 1,
tempEq : {$eq : ["$total_children", "$total_dates"]}
}
},
{
$match : {'tempEq' : true}
},
{
$group : {
_id : '$_id.parent',
dates : {$addToSet : "$_id.dates"}
}
}
])
这将产生以下输出:
{ "_id" : 1, "dates" : [ "2016-02-01", "2016-02-03" ] }
{ "_id" : 2, "dates" : [ "2016-02-02" ] }
希望这能有所帮助。您能编辑您的问题,将预期的输出文档也包括在内吗?非常感谢!第一个我不能使用,因为数组元素的数量没有定义,可以有多个子元素。第二个是一个开心果!这是如此简单,正是我所需要的!我不知道我在想什么:)@arawind真正的问题是,第二个过程与你正在做的事情是一样的,从不同的角度来看。嘿,谢谢,但公认的答案要简单得多:)欢迎。。在我的情况下,我假设你的父母可能有两个以上的孩子。:)你的假设是正确的,被接受答案的后半部分就是答案。如果我没有错的话,你也在遵循类似的方法?而且可能您的大多数聚合阶段都可以合并为一个。。