带有位置条件的 MongoDB 分页

Posted

技术标签:

【中文标题】带有位置条件的 MongoDB 分页【英文标题】:MongoDB pagination with location criteria 【发布时间】:2019-10-18 22:39:50 【问题描述】:

我想要按字段排序的数据。例如

db.Users.find().limit(200).sort('rating': -1).skip(0)

它的工作,我得到排序的数据。并且可以使用分页。

但是,如果添加条件.find('location':$near : [12,32], $maxDistance: 10) 排序将无法正常工作。

完整的查询:

db.Users.find('location':$near : [12,32], $maxDistance: 10).limit(200).sort('rating': -1).skip(0)

例如

无条件位置:

偏移量 0

rating 100
rating 99
rating 98
rating 97
rating 96

偏移量 5

rating 95
rating 94
rating 93
rating 92
rating 91

偏移 10

rating 90
rating 89
rating 88
rating 87
rating 86

有条件的位置

偏移量 0

rating 100
rating 99
rating 98
rating 97
rating 96

偏移量 5

rating 90
rating 89
rating 88
rating 87
rating 86

偏移 10

rating 95
rating 94
rating 93
rating 92
rating 91

可能是什么问题?我可以在 MongoDB 中使用带有位置条件的分页吗?

【问题讨论】:

【参考方案1】:

聚合框架可以使用$geoNear 管道阶段执行此操作。基本上它会“投射”一个“距离”字段,然后您可以在组合排序中使用它:

db.collection.aggregate([
     "$geoNear": 
        "near": [12,32],
        "distanceField": "distance",
        "maxDistance": 10
    ,
     "$sort":  "distance": 1, "rating" -1  
     "$skip": 0 ,
     "$limit": 25 
])

应该没问题,但是“skip”和“limit”对于大的skip并不是很有效。如果您无需“页码”即可摆脱困境,只想继续前进,那么请尝试不同的技术。

基本原则是跟踪为页面找到的最后一个距离值以及来自该页面或之前几个文档的 _id 值,然后可以使用 $nin 运算符将其过滤掉:

db.collection.aggregate([
     "$geoNear": 
        "near": [12,32],
        "distanceField": "distance",
        "maxDistance": 10,
        "minDistance": lastSeenDistanceValue,
        "query":  
            "_id":  "$nin": seenIds ,
            "rating":  "$lte": lastSeenRatingValue  
        ,
        "num": 25
    ,
     "$sort":  "distance": 1, "rating": -1 
])

基本上这会好很多,但它不会帮助您跳转到例如“页面”25。并非没有更多的努力来解决这个问题。

【讨论】:

以上是关于带有位置条件的 MongoDB 分页的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB动态条件之分页查询

springboot jpa mongodb 多条件分页查询

如何在带有自定义过滤器的 Spring Data mongodb 中使用分页和排序?

Spring Data MongoDB聚合分页查询中SkipOPeration和LimitOperation的位置

带有条件的MongoDB聚合查询

java mongodb查询条件