aru*_*414 3 mongodb mongodb-query aggregation-framework
在 $lookup 之后,我将得到一个名为 lastViewed 的连接,如下所示:
{
"_id" : "5955ea4fd8099718330ab191"
lastViewed: [
{
"_id" : ObjectId("595218a7d346d27fb0bc1705"),
"userId" : ObjectId("58c796d4344b9da4dfbe027b"),
"groupId" : ObjectId("5955ea4fd8099718330ab191"),
"lastViewedTime" : ISODate("2017-06-19T09:39:07.374Z")
},
{
"_id" : ObjectId("595218a7d346d27fb0bc1764"),
"userId" : ObjectId("58c796d4344b9da4dfbe027b"),
"groupId" : ObjectId("5955ea4fd8099718330ab162"),
"lastViewedTime" : ISODate("2017-05-11T09:39:07.374Z")
}
]
}
Run Code Online (Sandbox Code Playgroud)
我想使用 $filter 然后使用 $project 值,我的查询位于从 params 获取 userId 的位置下方
$project: { "viewedDetails": {
"$filter": {
"input": "$lastViewed",
"as": "lastViewed",
"cond": { $and: [{ "$eq": ["$$lastViewed.userId", mongoose.Types.ObjectId(userId)] }, { "$eq": ["$$lastViewed.groupId", '$_id'] }] }
}
}
}
Run Code Online (Sandbox Code Playgroud)
我得到了 userId 58c796d4344b9da4dfbe027b 的确切输出,如下所示
{
"_id" : "5955ea4fd8099718330ab191"
viewedDetails: [
{
"_id" : ObjectId("595218a7d346d27fb0bc1705"),
"userId" : ObjectId("58c796d4344b9da4dfbe027b"),
"groupId" : ObjectId("5955ea4fd8099718330ab191"),
"lastViewedTime" : ISODate("2017-06-19T09:39:07.374Z")
}
]
}
Run Code Online (Sandbox Code Playgroud)
现在我将模式更改为并得到 $lookup 结果为
{
"_id" : "5955ea4fd8099718330ab191"
lastViewed: [
{
"_id" : ObjectId("595218a7d346d27fb0bc1705"),
"userId" : ObjectId("58c796d4344b9da4dfbe027b"),
"members":[
{
"groupId" : ObjectId("5955ea4fd8099718330ab162"),
"lastViewedTime" : ISODate("2017-05-11T09:39:07.374Z")
}
{
"groupId" : ObjectId("5955ea4fd8099718330ab191"),
"lastViewedTime" : ISODate("2016-05-19T09:39:07.374Z")
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
那么我的对象数组过滤器不起作用,我的查询是
$project: { "viewedDetails": {
"$filter": {
"input": "$lastViewed",
"as": "lastViewed",
"cond": { $and: [{ "$eq": ["$$lastViewed.userId", mongoose.Types.ObjectId(userId)] },
{ "$eq": ["$$lastViewed.members.groupId", '$_id'] }] }
}
}
},
Run Code Online (Sandbox Code Playgroud)
我怎样才能在不使用 $unwind 然后使用 $project 的情况下得到这个?
不需要$unwind纯粹为了比较,因为有多种运算符可以通过与列表比较来确定逻辑结果。你真的只需要改变cond这里的$filter;
过滤“成员”需要包装$map以反映更改:
对于 MongoDB 3.4,您可以使用$in:
"viewedDetails": {
"$map": {
"input": {
"$filter": {
"input": "$lastViewed",
"as": "lastViewed",
"cond": {
"$and": [
{ "$eq": ["$$lastViewed.userId", mongoose.Types.ObjectId(userId)] },
{ "$in": [ "$_id", "$$lastViewed.members.groupId" ] }
]
}
}
},
"as": "v",
"in": {
"_id": "$$v._id",
"userId": "$$v.userId",
"members": {
"$filter": {
"input": "$$v.members",
"as": "m",
"cond": { "$eq": [ "$$m.groupId", "$_id" ] }
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
它将值与返回的数组中的每个值进行比较,"$$lastViewed.members.groupId"并返回trueorfalse取决于它是否匹配。
如果无法使用$in,则只需将初始的$filter更改为以下之一:
早于tat使用$setIsSubset
"cond": {
"$and": [
{ "$eq": ["$$lastViewed.userId", mongoose.Types.ObjectId(userId)] },
{ "$setIsSubset": [ ["$_id"], "$$lastViewed.members.groupId" ] }
]
}
Run Code Online (Sandbox Code Playgroud)
"cond": {
"$and": [
{ "$eq": ["$$lastViewed.userId", mongoose.Types.ObjectId(userId)] },
{ "$gt": [
{ "$size": {
"$setIntersection": [
["$_id"],
"$$lastViewed.members.groupId"
]
}},
0
] }
]
}
Run Code Online (Sandbox Code Playgroud)
导致具有“多个”0元素的“集合”的“交集”意味着该值存在于同一引用数组中。
请注意,在这些形式中,我们将"$_id"值设置为数组,["$_id"]因为“集合比较”是在“集合”之间而不是单个字段之间。
这是您提供的包含语法更正的文档:
{
"_id" : ObjectId("5955ea4fd8099718330ab191"),
"lastViewed" : [
{
"_id" : ObjectId("595218a7d346d27fb0bc1705"),
"userId" : ObjectId("58c796d4344b9da4dfbe027b"),
"members" : [
{
"groupId" : ObjectId("5955ea4fd8099718330ab162"),
"lastViewedTime" : ISODate("2017-05-11T09:39:07.374Z")
},
{
"groupId" : ObjectId("5955ea4fd8099718330ab191"),
"lastViewedTime" : ISODate("2016-05-19T09:39:07.374Z")
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
这是正在运行的管道阶段:
db.collection.aggregate([
{ "$project": {
"viewedDetails": {
"$map": {
"input": {
"$filter": {
"input": "$lastViewed",
"as": "lastViewed",
"cond": {
"$and": [
{ "$eq": [ "$$lastViewed.userId", ObjectId("58c796d4344b9da4dfbe027b") ] },
{ "$in": [ "$_id", "$$lastViewed.members.groupId" ] }
]
}
}
},
"as": "v",
"in": {
"_id": "$$v._id",
"userId": "$$v.userId",
"members": {
"$filter": {
"input": "$$v.members",
"as": "m",
"cond": { "$eq": [ "$$m.groupId", "$_id" ] }
}
}
}
}
}
}}
])
Run Code Online (Sandbox Code Playgroud)
这是输出:
{
"_id" : ObjectId("5955ea4fd8099718330ab191"),
"viewedDetails" : [
{
"_id" : ObjectId("595218a7d346d27fb0bc1705"),
"userId" : ObjectId("58c796d4344b9da4dfbe027b"),
"members" : [
{
"groupId" : ObjectId("5955ea4fd8099718330ab191"),
"lastViewedTime" : ISODate("2016-05-19T09:39:07.374Z")
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10485 次 |
| 最近记录: |