如何将匹配文档的子文档合并为一个并将其作为对象数组返回?我试过$group
,但似乎没有用。
我的查询(这个返回数组的对象在这种情况下有两个)
User.find({
'business_details.business_location': {
$near: coords,
$maxDistance: maxDistance
},
'deal_details.deals_expired_date': {
$gte: new Date()
}
}, {
'deal_details': 1
}).limit(limit).exec(function(err, locations) {
if (err) {
return res.status(500).json(err)
}
console.log(locations)
console.log(位置)结果 //给我下面的结果
[{
_id: 55 c0b8c62fd875a93c8ff7ea, // first document
deal_details: [{
deals_location: '101.6833,3.1333',
deals_price: 12.12 // 1st deal
}, {
deals_location: '101.6833,3.1333',
deals_price: 34.3 // 2nd deal
}],
business_details: {}
}, {
_id: 55 a79898e0268bc40e62cd3a, // second document
deal_details: [{
deals_location: '101.6833,3.1333',
deals_price: 12.12 // 3rd deal
}, {
deals_location: '101.6833,3.1333',
deals_price: 34.78 // 4th deal
}, {
deals_location: '101.6833,3.1333',
deals_price: 34.32 // 5th deal
}],
business_details: {}
}]
我想要做的是将这两个deal_details字段组合在一起并将其作为对象数组返回。它将在一个对象数组中包含5个交易,而不是两个分开的对象数组。
我试图通过使用concat或push在我的后端(nodejs)中执行此操作,但是当有超过2个匹配文档我有问题将它们连接在一起时,是否有任何方法可以合并所有匹配文件并将其作为一个归还?就像我上面提到的那样?
答案 0 :(得分:2)
这里可能缺少的是$unwind
管道阶段,这是您通常用于“规范化”数组内容的阶段,特别是当您的分组操作打算在查询结果中跨文档工作时: / p>
User.aggregate(
[
// Your basic query conditions
{ "$match": {
"business_details.business_location": {
"$near": coords,
"$maxDistance": maxDistance
},
"deal_details.deals_expired_date": {
"$gte": new Date()
}},
// Limit query results here
{ "$limit": limit },
// Unwind the array
{ "$unwind": "$deal_details" },
// Group on the common location
{ "$group": {
"_id": "$deal_details.deals_location",
"prices": {
"$push": "$deal_details.deals_price"
}
}}
],
function(err,results) {
if (err) throw err;
console.log(JSON.stringify(results,undefined,2));
}
);
其中输出如下:
{
"_id": "101.6833,3.1333",
"prices": [
12.12,
34.3,
12.12,
34.78,
34.32
]
}
取决于实际与分组匹配的文档数量。
或者,您可能希望查看$geoNear
管道阶段,它可以提供更多控制,尤其是在处理数组中的内容时。
还要注意,对于数组中的“location”数据,此处仅考虑“最近”的结果,而不考虑数组内容的“全部”结果。因此,数组中的其他项可能实际上并非“接近”查询点。这更像是一个设计考虑因素,因为您执行的任何查询操作都需要考虑这一点。
答案 1 :(得分:1)
您可以将它们与reduce
合并:
locations = locations.reduce(function(prev, location){
previous = prev.concat(location.deal_details)
return previous
},[])