我最近在尝试使用非唯一字段(例如“FirstName”)对请求进行分页时遇到了同样的问题。这个查询的想法是能够在不使用skip()的情况下对非唯一字段实现分页
这里的主要问题是能够查询不是唯一的“FirstName”字段,因为会发生以下情况:
- $gt: {"FirstName": "Carlos"} -> 这将跳过名字为“Carlos”的所有记录
- $gte: {"FirstName": "Carlos"} -> 将始终返回相同的数据集
因此,我想出的解决方案是通过将目标搜索字段与辅助字段组合来使查询的 $match 部分唯一,以使其成为唯一搜索。
升序:
db.customers.aggregate([
{$match: { $or: [ {$and: [{'FirstName': 'Carlos'}, {'_id': {$gt: ObjectId("some-object-id")}}]}, {'FirstName': {$gt: 'Carlos'}}]}},
{$sort: {'FirstName': 1, '_id': 1}},
{$limit: 10}
])
降序:
db.customers.aggregate([
{$match: { $or: [ {$and: [{'FirstName': 'Carlos'}, {'_id': {$gt: ObjectId("some-object-id")}}]}, {'FirstName': {$lt: 'Carlos'}}]}},
{$sort: {'FirstName': -1, '_id': 1}},
{$limit: 10}
])
这个查询的 $match 部分基本上表现为一个 if 语句:
如果 firstName 是“Carlos”,那么它也需要大于这个 id
如果 firstName 不等于“Carlos”,则它需要大于“Carlos”
唯一的问题是您无法导航到特定的页码(可能可以通过一些代码操作来完成),但除此之外它解决了我的非唯一字段分页问题,而不必使用跳过会吃很多东西到达您要查询的任何数据集的末尾时的内存和处理能力。