【问题标题】:How to sort by other field in $geonear aggregation pipeline in mongodb如何在 mongodb 的 $geonear 聚合管道中按其他字段排序
【发布时间】:2014-08-14 12:39:53
【问题描述】:

我的收藏有这种格式。

{
    "_id" : ObjectId("52e5f94d83b45407f959e7ff"),

    "latlng" : {
        "coordinates" : [
            85.29035240000007,
            27.6663671
        ],
        "type" : "Point"
    },
    "name" : "Sujit Maharjan",
    "updates" : [
        {
            "status" : "I want to #buy 5 kg of tomatoes.",
            "picture" : [ ],
            "parent_tweet_id" : "0",
            "deleted" : 1,
            "tweet_id" : "428578269169205248",
            "time_stamp" : 1391015996
        }
        {
            "status" : "I want to #start #milk business who can help me ?",
            "picture" : [ ],
            "parent_tweet_id" : "0",
            "deleted" : 0,
            "tweet_id" : "108fd43a-7efa-404d-800d-0c30a5da06e5",
            "time_stamp" : 1391955084
        },
        {
            "status" : "@SantoshGhimire @bhanduroshan Connect to us for  #Dairy business",
            "picture" : [ ],
            "parent_tweet_id" : "432503201968168960",
            "deleted" : 1,
            "tweet_id" : "432517594026082304",
            "time_stamp" : 1391955208
        },
        {
            "status" : "@bhanduroshan Did you get my message ?",
            "picture" : [ ],
            "parent_tweet_id" : "432502654154334208",
            "deleted" : 0,
            "tweet_id" : "432788670463377408",
            "time_stamp" : 1392019838
        },
        {
            "status" : "this is tweet with images @foodtradeHQ http://t.co/3eL1351HWf",
            "picture" : [
                "http://pbs.twimg.com/media/BgLZ4YaCUAAsFTJ.jpg"
            ],
            "parent_tweet_id" : "0",
            "deleted" : 1,
            "tweet_id" : "433148076820156417",
            "time_stamp" : 1392105574
        }
    ]
}

现在我需要查询用户在某个半径内的更新,按updates.time_stamp排序。

为此,我使用了聚合管道,但 $geonear 查询会从距离排序并限制结果。

这是我在 python 中的管道

    geo_search = {"near": [float(self.lng), float(self.lat)],
                               "distanceField": "distance",
                                "includeLocs": "latlng",
                                "uniqueDocs": True,
                                "spherical":True,
                                "limit":100,  # this will cut off the possible results, and complexity increasing in increasing this number
                            }



    pipeline = []

    final_query = {"$and":query_string}

    if len(query_string)>0:
        geo_search['query'] = final_query


    geo_search['maxDistance'] = 0.01261617096

    geo_near = {
                    "$geoNear": geo_search
                  }


    pipeline.append(geo_near)

【问题讨论】:

    标签: python mongodb mongodb-query aggregation-framework pymongo


    【解决方案1】:

    使用$geoNear 聚合管道阶段,这基本上执行标准类型的“nearSphere”或“near”类似查询,但将结果文档放置在管道中,并带有distanceField 所需的附加字段。

    必须是第一个管道阶段,它可以在其中使用索引:

     collection.aggregate([
         { "$geoNear": {
             "near": [ float(self.lng), float(self.lat) ],
             "maxDistance": 0.01261617096,
             "distanceField": "distance",
             "includeLocs": "latlng",
             "uniqueDocs": True,
             "spherical":True,
             "query": {
                 "updates.time_stamp": {
                     "$gte": timestamp_cutoff
                 }
             },
             "limit":100
         }},
         { "$sort": { "other": 1, "distance": 1 } }
    ])
    

    通过管道的其余部分,现在有了“distanceField”中定义的附加字段,因此为了获得最接近的结果,请将其传递给$sort。你可以传递任何你想要排序的东西,因为这是管道阶段所做的。

    您基本上可以使用您喜欢的任何内容对结果进行操作,包括$match 等其他阶段。当然,如果其他信息与初始结果相关,那么您可以使用$geoNear 的“查询”选项。

    真正做你想做的事,你需要通过在“查询”中使用一些东西来“限制”匹配的可能文档,如图所示。因此,返回的“最近”文档仅是那些符合附加条件的文档。

    【讨论】:

    • 但问题是限制查询已经截断了其他可能的结果,因为mongodb$geoNear 按照离指定点最近到最远的顺序返回文档并将文档通过聚合管道。
    • @SujitMaharjan 文档中的所有字段都将返回,除非您在 $geoNear 之后放置 $project 来更改此设置。您只需将字段传递到您真正想要的$sort 阶段。这就是答案所说的。
    • 问题是 $geonear 中的 limit 字段。我需要对半径内的所有结果进行排序。
    • @SujitMaharjan GeoNear 根据定义寻找“最近”的文档,因此距离是关键。如果您希望排除某个时间范围之外的结果,那么您始终可以将该条件传递给“查询”和/或只是增加“限制”,然后对结果进行排序并改用$limit 管道阶段。这不会改变函数的性质,但通过调整这些参数,您可以朝着您的结果努力。
    • 是的,我在 $geonear 的限制字段中使用了非常高的数字,但它太慢了。
    猜你喜欢
    • 2017-11-04
    • 1970-01-01
    • 2020-10-12
    • 2013-04-29
    • 2018-08-06
    • 2022-11-12
    • 2023-03-21
    • 2018-08-25
    • 1970-01-01
    相关资源
    最近更新 更多