我在这里要做的是查询并合并多个子文档作为数组。我认为聚合框架是可行的方法,但我似乎无法完全正确。
以下是我的名为访客的集合:
{
"_id": ObjectId("57dc5c2b7463d336ec3fff8c"),
"username": "Bob",
"fullname": "Bobby",
"activities":
{ "visits" : [
{
"_id": ObjectId("57dc674e4208b12fd4a52a3d"),
"date": ISODate("2016-09-18T08:00:00.000Z"),
"location" : "Jakarta",
},
{
"_id": ObjectId("57dd3795c13c5e2b7484ea4b"),
"date": ISODate("2016-09-17T08:00:00.000Z"),
"location" : "Denpasar",
}
],
"purchases" : [
{
"_id": ObjectId("57dc4769c0f09317282b3f92"),
"date": ISODate("2016-09-17T07:30:00.000Z"),
"product_name" : "Shirt",
"price": 125000
},{
"_id": ObjectId("57dbfdc6be9dcf1e7c4a1751"),
"date": ISODate("2016-09-18T08:30:00.000Z"),
"product_name" : "Shoes",
"price": 150000
}
]},
}
}
这是文档 我想要并尝试使用聚合来实现这一点,条件是我可以按日期sort
使用{ {1}}和limit
。
skip
我一直试图通过这种聚合
来做到这一点{
"_id": ObjectId("57dc5c2b7463d336ec3fff8c"),
"activities": [
{
"activity_type": "purchases",
"_id": ObjectId("57dbfdc6be9dcf1e7c4a1751"),
"date": ISODate("2016-09-18T08:30:00.000Z"),
"product_name" : "Shoes",
"price": 150000
},{
"activity_type": "visits",
"visits_id": ObjectId("57dc674e4208b12fd4a52a3d"),
"date": ISODate("2016-09-18T08:00:00.000Z"),
"location" : "Jakarta",
},{
"activity_type": "visits",
"visits_id": ObjectId("57dd3795c13c5e2b7484ea4b"),
"date": ISODate("2016-09-17T08:00:00.000Z"),
"location" : "Denpasar",
},{
"activity_type": "purchases",
"date": ISODate("2016-09-17T07:30:00.000Z"),
"product_name" : "Shirt",
"price": 125000
}]
}
但是我没有得到我想要的东西,而是根据他们的类型对它们进行分组,我甚至无法使用db.visitors.aggregate([{
$match: { _id: ObjectId("57dc5c2b7463d336ec3fff8c") } },
{
$group: {
_id: "$_id",
visits: {
"$addToSet": "$activities.visits"
},
purchases: {
"$addToSet": "$activities.purchases"
}
}
}])
和skip
(似乎只是跳过并限制访问者)数)。
limit
我已尝试使用{
"_id": ObjectId("57dc5c2b7463d336ec3fff8c"),
"visits": [
[
{
"_id": ObjectId("57dc674e4208b12fd4a52a3d"),
"date": ISODate("2016-09-18T08:00:00.000Z"),
"location" : "Jakarta",
},
{
"_id": ObjectId("57dd3795c13c5e2b7484ea4b"),
"date": ISODate("2016-09-17T08:00:00.000Z"),
"location" : "Denpasar",
}
]
],
"news": [
[
{
"_id": ObjectId("57dc4769c0f09317282b3f92"),
"date": ISODate("2016-09-17T07:30:00.000Z"),
"product_name" : "Shirt",
"price": 125000
},{
"_id": ObjectId("57dbfdc6be9dcf1e7c4a1751"),
"date": ISODate("2016-09-18T08:30:00.000Z"),
"product_name" : "Shoes",
"price": 150000
}
]
]
}
,
unwind
但它似乎在每个索引合并不同类型的文档
db.visitors.aggregate([
{ $match: { _id: ObjectId("57dc5c2b7463d336ec3fff8c") } },
{ $unwind: '$activities.visits' },
{ $unwind: '$activities.purchases' },
{ $project: {
_id: 0,
//visits
"visits_id": "$activities.visits._id",
"visits_date": "$activities.visits.date",
"visits_location" : "$activities.visits.location"
//purchases
"purchases_id": "$activities.purchases._id",
"purchases_date": "$activities.purchases.date",
"purchases_product_name": "$activities.purchases.product_name",
"purchases_price": "$activities.purchases.price",
}
}
])
.skip(0)
.limit(2)
是否可以使用我当前的文档执行此操作?或者我应该更改我的文档结构?
更新已解决
我最后在数组的每个子文档中添加{
"_id": ObjectId("57dc5c2b7463d336ec3fff8c"),
"activities": [
{
"purchases_id": ObjectId("57dbfdc6be9dcf1e7c4a1751"),
"purchases_date": ISODate("2016-09-18T08:30:00.000Z"),
"purchases_product_name" : "Shoes",
"purchases_price": 150000
"visits_id": ObjectId("57dc674e4208b12fd4a52a3d"),
"visits_date": ISODate("2016-09-18T08:00:00.000Z"),
"visits_location" : "Jakarta",
},{
"purchases_id": ObjectId("57dc4769c0f09317282b3f92"),
"purchases_date": ISODate("2016-09-17T07:30:00.000Z"),
"purchases_product_name" : "Shirt",
"purchases_price": 125000
"visits_id": ObjectId("57dd3795c13c5e2b7484ea4b"),
"visits_date": ISODate("2016-09-17T08:00:00.000Z"),
"visits_location" : "Denpasar",
}]
}
,并使用activity_type
解决此问题,将多个数组合并为数组,并使用$setUnion
限制并跳过数组。我不知道如何,但似乎$slice
已经自动对其进行排序
$setUnion
答案 0 :(得分:1)
如果您为每个数组元素添加activity_type
字段,则$setUnion
一个aggregation
阶段将很容易使用{<1}}:
db.visitors.aggregate([
{
$project: {
activities: {
$setUnion: ['$activities.visits', '$activities.purchases']
}
}
}
])
在这种情况下,您将把数组“连接”在一起,形成一个带有类型的活动数组。
对于问题的其他部分,sort
,skip
,limit
是聚合阶段,可以处理每个文档而不是子文档,因此您需要{ {1}}您需要的文档,$match
之前的结果$unwind
数组,然后您就可以使用activities
,sort
,skip
运算符。