情景:
我有一个集合来保存 sessionLogs ,其中包含以下属性:
我还有 actionLogs 的另一个集合:
我无法在actionLogs上引用sessionLog,或者在sessionLog记录中的子集合上添加actionLogs ......这是因为应用程序的性质。 (我认为没有必要为当前的问题解释这一点)
问题:
我需要获得具有特定actionLog的sessionLog的 LIST 。 (以及其他过滤器,如日期,用户等......)
如何仅使用查询执行实现结果?
我认为该组应该使用日期(startDate,endDate),userId和deviceType。
示例:
会话日志
与该SessionLog相关的操作日志
答案 0 :(得分:2)
好吧,如果我理解得很好,可以使用$lookup和$unwind(可选)阶段来实现。
由于查找已经"合并/加入"我们的收藏集,以便您通过$match的$group阶段通过aggregation pipeline阶段和群组查询任何条件:
我们考虑以下集合:
var sessionsLog = [
{
'userId': "132",
'deviceType': "ios",
'startDate': ISODate('2018-02-23'),
'endDate': ISODate('2018-02-28')
},
{
'userId': "789",
'deviceType': "android",
'startDate': ISODate('2018-02-15'),
'endDate': ISODate('2018-02-19')
},
{
'userId': "225",
'deviceType': "ios",
'startDate': ISODate('2018-03-01'),
'endDate': ISODate('2018-03-17')
}
];
var actionsLog = [
{
'userId': '225',
'deviceType': 'ios',
'createdAt': ISODate('2018-03-03'),
'action': 'X'
},
{
'userId': '789',
'deviceType': 'android',
'createdAt': ISODate('2018-02-16'),
'action': 'Y'
},
{
'userId': '789',
'deviceType': 'android',
'createdAt': ISODate('2018-02-16'),
'action': 'Z'
}
];
db.actionLogs.insert(actionsLog); //via mongo shell...
db.sessionLogs.insert(sessionsLog); //via mongo sheell...
当$lookup运营商派上用场时。在这里,我们将加入userId
字段的馆藏,但这取决于你" wire"按字段收集你想要的东西!
db.sessionLogs.aggregate([
{
$lookup: {
from: 'actionLogs',
foreignField: 'userId',
localField: 'userId',
as: 'action_log'
}
}
])
我需要获取具有特定actionLog的sessionLog的LIST。 (以及其他过滤器,如日期,用户等......)
一旦我们加入了集合,就可以使用$match运算符按照特定条件轻松获取/过滤文档。
但在此之前,我认为在$unwind阶段之前添加$match阶段确实使工作变得更容易(但根本不需要),所以它将是:
db.sessionLogs.aggregate([
{
$lookup: {
from: 'actionLogs',
foreignField: 'userId',
localField: 'userId',
as: 'action_log'
}
},
{
$unwind: '$action_logs'
}
])
它返回:
{
"_id": ObjectId("5ab463233a856b4829f5e75d"),
"userId": "789",
"deviceType": "android",
"startDate": ISODate("2018-02-15T00:00:00Z"),
"endDate": ISODate("2018-02-19T00:00:00Z"),
"action_log": {
"_id": ObjectId("5ab463363a856b4829f5e760"),
"userId": "789",
"deviceType": "android",
"createdAt": ISODate("2018-02-16T00:00:00Z"),
"action": "Y"
}
},
{
"_id": ObjectId("5ab463233a856b4829f5e75d"),
"userId": "789",
"deviceType": "android",
"startDate": ISODate("2018-02-15T00:00:00Z"),
"endDate": ISODate("2018-02-19T00:00:00Z"),
"action_log": {
"_id": ObjectId("5ab463363a856b4829f5e761"),
"userId": "789",
"deviceType": "android",
"createdAt": ISODate("2018-02-16T00:00:00Z"),
"action": "Z"
}
},
{
"_id": ObjectId("5ab463233a856b4829f5e75e"),
"userId": "225",
"deviceType": "ios",
"startDate": ISODate("2018-03-01T00:00:00Z"),
"endDate": ISODate("2018-03-17T00:00:00Z"),
"action_log": {
"_id": ObjectId("5ab463363a856b4829f5e75f"),
"userId": "225",
"deviceType": "ios",
"createdAt": ISODate("2018-03-03T00:00:00Z"),
"action": "X"
}
}
现在我们可以过滤这样的文档(其中action等于X):
db.sessionLogs.aggregate([
{
$lookup: {
from: 'actionLogs',
foreignField: 'userId',
localField: 'userId',
as: 'action_log'
}
},
{
$unwind: '$action_log'
},
{
$match: {'action_log.action': 'X' }
}
])
以同样的方式,通过为聚合管道添加$group阶段进行分组应该非常简单!
侧面说明: