gpt4 book ai didi

mongodb - 在 $lookup 上使用 Foriegn Collection 的 $geowithin

转载 作者:可可西里 更新时间:2023-11-01 10:40:20 26 4
gpt4 key购买 nike

我有两个集合 Members 和 MobileUserLocations - 每个用户位置都保存(可以是多个)作为 userId 作为外部字段。

成员:

{
_id: ObjectId("591553ffa4233a181506880c"),
userName: "Test user"
}

移动用户位置:

{ _id: ObjectId("59156070a4233a1815068b6b"),
userId: ObjectId("591553ffa4233a181506880c"),
location: {type: "Point", coordinates: [76.9121, 10.2232]]},
updatedOn: 2017-05-12T07:12:48.626Z,
status: 1
},
{ _id: ObjectId("59156070a4233a1815068b6b"),
userId: ObjectId("591553ffa4233a181506880c"),
location: {type: "Point", coordinates: [76.8121, 10.1232]]},
updatedOn: 2017-05-12T07:12:48.626Z,
status: 1
}

我想获取半径范围内的成员 - 例如 5 公里引用特定地理点 - 例如:[10.0132295, 76.3630502](lat,lng 格式)。

我试过这个:

collection.aggregate([
{$match: {_id: { $ne: options.accessToken.userId }},
{ "$lookup": {
"localField": "_id",
"from": "MobileUserLocations",
"foreignField": "userId",
"as": "userLocInfo"
}
},
{
$project: {
_id: 1,
userLocInfo: {
"$filter": {
"input": "$userLocInfo",
"as": "userLoc",
"cond": {
"$eq": [ "$$userLoc.status", -1],
"$$userLoc.location": {"$geoWithin": {"$centerSphere": [[76.3630502, 10.0132295], 5 / 3963.2]}}
}
}
}
}
},
{$unwind: "$userLocInfo"}

]

但是没有得到。如果我从过滤器 cond 中删除 $geowithin,它会获取,否则不会获取。但如果我单独查询集合,我会得到结果。

谁能知道这个问题?

最佳答案

那是行不通的,因为 $geoWithin不是“逻辑运算符”,而是“查询运算符”,只能在使用 $match 的聚合管道中使用.幸运的是,这正是您想要的。虽然你还不明白为什么:

collection.aggregate([
{ "$match": {
"_id": { "$ne": options.accessToken.userId }
}},
{ "$lookup": {
"localField": "_id",
"from": "MobileUserLocations",
"foreignField": "userId",
"as": "userLocInfo"
}},
{ "$unwind": "$userLocInfo" },
{ "$match": {
"userLocInfo.status": -1,
"userLocInfo.updatedOn": "2017-05-12T12:11:04.183Z",
"userLocInfo.location": {
"$geoWithin": {
"$centerSphere": [[76.3630502, 10.0132295], 5 / 3963.2]
}
}
}}
])

除了它是唯一的工作方式之外,还有一个很好的理由。要理解,请查看 "explain" 输出:

    {
"$lookup" : {
"from" : "MobileUserLocations",
"as" : "userLocInfo",
"localField" : "_id",
"foreignField" : "userId",
"unwinding" : {
"preserveNullAndEmptyArrays" : false
},
"matching" : {
"$and" : [
{
"status" : {
"$eq" : -1.0
}
},
{
"updatedOn" : {
"$eq" : "2017-05-12T12:11:04.183Z"
}
},
{
"location" : {
"$geoWithin" : {
"$centerSphere" : [
[
76.3630502,
10.0132295
],
0.00126160678239806
]
}
}
}
]
}
}
}

向您展示的是$unwind和以下 $match融入 $lookup舞台本身。这意味着 $geoWithin和其他条件实际在外部集合上执行 “之前” 结果返回。

这就是$lookup处理可能违反 16MB 限制的结果连接。这也是目前“过滤”连接结果的最有效方式。

所以这才是您真正想在这里做的事情。


根据您问题中的数据,此声明:

db.members.aggregate([
{ "$lookup": {
"localField": "_id",
"from": "MobileUserLocations",
"foreignField": "userId",
"as": "userLocInfo"
}},
{ "$unwind": "$userLocInfo" },
{ "$match": {
"userLocInfo.location": {
"$geoWithin": {
"$centerSphere": [[76.9121, 10.2232], 5 / 3963.2]
}
}
}}
])

过滤掉 $lookup 中与约束条件匹配的一个位置:

/* 1 */
{
"_id" : ObjectId("591553ffa4233a181506880c"),
"userName" : "Test user",
"userLocInfo" : {
"_id" : ObjectId("59c3c37359f55d64d6e30297"),
"userId" : ObjectId("591553ffa4233a181506880c"),
"location" : {
"type" : "Point",
"coordinates" : [
76.9121,
10.2232
]
},
"updatedOn" : ISODate("2017-05-12T07:12:48.626Z"),
"status" : 1.0
}
}

关于mongodb - 在 $lookup 上使用 Foriegn Collection 的 $geowithin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46341546/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com