MongoDB:使用过滤器

时间:2018-09-11 00:48:50

标签: javascript node.js mongodb express mongoose

在MongoDB中,我有UserTokenBoost的模型。

用户可以拥有一个或多个令牌以及一个或多个提升。

Token有一个2dsphere位置字段。

并且Boost具有startTimestopTime日期字段。

如果Date.now()大于boost.startTime()但小于boost.stopTime(),则表示用户具有主动提升功能。

我可以编写哪种Mongo聚合来获取特定位置附近的至少具有一个主动提升用户的所有令牌?

1 个答案:

答案 0 :(得分:1)

根据您的问题,我创建了一个模拟数据

token collection:
{
    "_id" : ObjectId("5b97541c6af22cc65216ffd8"),
    "userid" : "5b9753726af22cc65216ffd6",
    "location" : {
        "longitude" : 80.250875,
        "latitude" : 13.052519
    }
},
{
    "_id" : ObjectId("5b97543a6af22cc65216ffd9"),
    "userid" : "5b97537e6af22cc65216ffd7",
    "location" : {
        "longitude" : 80.249995,
        "latitude" : 13.051819
    }
}

boost collection :
{
        "_id" : ObjectId("5b9754796af22cc65216ffda"),
        "startTime" : ISODate("2018-09-11T05:36:57.149Z"),
        "stopTime" : ISODate("2018-09-11T05:36:57.149Z"),
        "userid" : "5b9753726af22cc65216ffd6"
    },
    {
        "_id" : ObjectId("5b9754b46af22cc65216ffdb"),
        "startTime" : ISODate("2018-10-08T18:30:00.000Z"),
        "stopTime" : ISODate("2018-10-08T18:30:00.000Z"),
        "userid" : "5b97537e6af22cc65216ffd7"
    }

Users collection :
{
            "_id" : ObjectId("5b9753726af22cc65216ffd6"),
            "userName" : "user111"
        },
        {
            "_id" : ObjectId("5b97537e6af22cc65216ffd7"),
            "userName" : "user222"
        }

要获取特定位置附近所有属于至少具有一次有效提升用户的令牌的总查询是:

 db.token.aggregate([
{
     "$geoNear": {
        "near": { type: "Point", coordinates: [80.248797,13.050599] },
        "distanceField": "location",
        "maxDistance": 1000,
        "includeLocs": "location",
        "spherical": true
     }
   },
   {"$lookup" : {"from":"boost",
                 "localField" : "userid",
                "foreignField" : "userid",
                 "as" : "boostDocs"
      }},
   {"$unwind" : "$boostDocs"},
   {"$match" : {"$and":[{"boostDocs.startTime":{"$lte":new Date("11/09/2018")}},{"boostDocs.stopTime":{"$gte":new Date("10/09/2018")}}]}}
   ])

请注意,与位置匹配的查询位于查询的顶部,因为$ geoNear仅在其聚合管道的第一阶段有效。 我用于比较的日期仅用于检查查询是否有效。您可以根据需要指定日期或Date.now()。