我有2个要基于特定属性加入的不同文档。 在第一个文档上,我想使用$ group根据属性对文档进行分组,然后使用结果将其与第二个文档联接。
我的第一个文档spotmodel
具有以下结构:
{
"_id" : ObjectId("5c17724498ea721018ba9d59"),
"code" : "AD01",
"streetId" : ObjectId("5c16d3e6e6cbea23a0393b4b")
},
{
"_id" : ObjectId("5c17724498ea721018ba9d60"),
"code" : "AD02",
"streetId" : ObjectId("5c16d3e6e6cbea23a0393b4b")
}
// other documents with same or different streetID
我的第二个文档areamodel
具有以下结构:
{
"_id" : ObjectId("5c16d339e6cbea23a0393b47"),
"description" : "Area A",
"streets" : [
{
"_id" : ObjectId("5c16d3e6e6cbea23a0393b4b"),
"name" : "Waterloo"
},
{
"_id" : ObjectId("5c16d536e6cbea23a0393b51"),
"name" : "Bristol"
}
]
}
,
{
"_id" : ObjectId("5c16d339e6cbea23a0393b47"),
"description" : "Area B",
"streets" : [
{
"_id" : ObjectId("5c16d3e6e6cbea23a0393b2a"),
"name" : "Park Av."
},
{
"_id" : ObjectId("5c16d536e6cbea23a0393b2b"),
"name" : "Nelson St."
}
]
}
我想基于spotmodel
对streetId
文档进行分组,并在areamodel
匹配streetId
时使用此分组查询与streets._id
文档进行合并>
到目前为止,我有以下查询:
db.spotmodel.aggregate([
{
$group: {
_id: "$streetId",
codes: {
$push: {
code: "$code",
}
}
}
},
{$lookup: {
from: "db.areamodel",
localField: "streets._id",
foreignField: "_id",
as: "details"
}},
{$match:{details:{$ne:[]}}}
])
但是此代码为我提供了一个空数组[]
,但我期望的结果是这样的:
{
"_id" : ObjectId("5c16d339e6cbea23a0393b47"),
"description" : "Area A",
"streets" : [
{
"_id" : ObjectId("5c16d3e6e6cbea23a0393b4b"),
"name" : "Waterloo",
"codes":[
{
"code": "AD01"
},
{
"code": "AD02"
}
]
},
{
"_id" : ObjectId("5c16d536e6cbea23a0393b51"),
"name" : "Bristol"
}
]
}
我的错误在哪里?
答案 0 :(得分:1)
您可以在aggregation
下使用
db.areamodel.aggregate([
{ "$unwind": "$streets" },
{ "$lookup": {
"from": "spotmodel",
"localField": "streets._id",
"foreignField": "streetId",
"as": "codes"
}},
{ "$addFields": { "streets.codes": "$codes.code" }},
{ "$group": {
"_id": "$_id",
"streets": { "$push": "$streets" },
"description": { "$first": "$description" }
}}
])
答案 1 :(得分:0)
在mongodb中,大型数据集的查找速度非常慢。 尝试对文档进行非规范化。
答案 2 :(得分:0)
// schema on nodejs via mongoose:
var mongoose = require('mongoose')
, Schema = mongoose.Schema
, ObjectId = Schema.ObjectId;
var flatSchema = new Schema({
_id: ObjectId,
rentType: Number,
price: Number,
thumbnail: String,
address: {
country: String,
city: String,
street: String,
district: Number
// ... more fields
}
// ... some more fields
}, { collection: 'flats'});
module.exports = mongoose.model('Flat', flatSchema);
-----
/ e.g. let's define request
var rules = [{'address.city': '1'}, {price: {$gte: 200}}];
// and here are the grouping request:
Flat.aggregate([
{ $match: {$and: rules } },
{
$project: {
_id: 0, // let's remove bson id's from request's result
price: 1, // we need this field
district: '$address.district' // and let's turn the nested field into usual field (usual renaming)
}
},
{
$group: {
_id: '$district', // grouping key - group by field district
minPrice: { $min: '$price'}, // we need some stats for each group (for each district)
maxPrice: { $max: '$price'},
flatsCount: { $sum: 1 }
}
}
], {}, callback);
First of all – it’s not possible to group by nested field, e.g. “address.district”, thats why we workarounded this by field’s renaming in $project.