在mongodb查询中获取项目的索引 [英] Get index of an item within mongodb query

查看:108
本文介绍了在mongodb查询中获取项目的索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个查询,如下所示:

I have a query which looks like:

function getPage(page) {
  return db.messages.aggregate(
    {
      '$group': {
        _id: "$subjectID"
      }
    },
    { '$skip': page * 20 },
    { '$limit' : 20 });
}

说我有一个subjectID,我知道它出现在该集合中的某个地方.我要写的是这样的东西:

Say I have a subjectID that I know appears somewhere in that collection. What I want to do is write something like:

function pageOf(subjectID) {
  return Math.floor(db.messages.aggregate(
    {
      '$group': {
        _id: "$subjectID"
      }
    }).indexOf({__id: subjectID}) / 20);
}

除了我不知道如何编写该查询的indexOf部分.我想知道mongodb是否可能有某种"while while"或"take until"查询,那么您可以做到这一点,然后计算项目数量.

Except I have no idea how to write the indexOf part of that query. I was wondering if mongodb might have some sort of "take while" or "take until" query, then you could do that followed by a count of the number of items.

推荐答案

按subjectID排序

如果您的subjectID是(或可以更改为)单调递增的值(例如,MongoDB默认ObjectID),则可以使用普通的find()具有适当的排序,跳过和限制的简单选项.在这种情况下,您可以查找主题ID为 $gte(大于或等于)的文档您的subjectID:

Ordering by subjectID

If your subjectID is (or can be changed to) a monotonically increasing value (for example, a MongoDB default ObjectID), you have a straightforward option using a normal find() with appropriate sort, skip, and limit. In this case you can look for documents with subjectIDs $gte (greater than or equal to) your subjectID:

var page = 1;
var subjectID = ObjectId("515535a0760fe8735f5f6897");
db.users.find(
    { _id: { $gte : subjectID } }
).sort({'_id':1}).skip(page*20).limit(20)

聚合框架

与MongoDb 2.4一样,聚合框架中没有此类功能可根据结果管道中的文档位置进行匹配.您可以提出新的功能建议,建议MongoDB Jira项目的 SERVER 队列.

听起来好像您想要一个新的管道运算符,例如$matchfrom,它将在第一次出现$matchfrom标准之前将忽略任何文档.然后,您可以添加$limit以获取下n个项目.您还希望在$matchfrom之前对输出进行排序,以便获得可预测的结果.

It sounds like you would want a new pipeline operator such as a $matchfrom which would ignore any documents until the first occurrence of the $matchfrom criteria. You could then add a $limit to take the next n items. You would also want to have sorted output before the $matchfrom so there is a predictable outcome.

与增加的subjectID相比,这似乎过于复杂,但是可能存在基于更高级的搜索标准或在聚合管道中计算出的结果进行分页的用例.

This seems overcomplicated compared to having an increasing subjectID, but there may be a use case for doing paging based on more advanced search criteria or results calculated in the aggregation pipeline.

除了将来在Aggregation Framework中对此类功能的支持之外,您还有一些选择可以在代码中实现相同的匹配方法:

Aside from future support for such a feature in the Aggregation Framework, you have a few options to implement the same matching approach in code:

  • 使用较早的 group() 聚合命令finalize()功能.注意:group() 不适用于分片群集.

  • use the older group() aggregation command with a finalize() function. NOTE: group() does not work with sharded clusters.

使用 MapReduce finalize()函数

从Aggregation Framework中获取整个结果集,并在应用程序代码中实现结果的匹配/约简(尽管如果您要为每个请求获取所有页面,这在某种程度上会破坏分页"的概念). /p>

fetch the whole result set from the Aggregation Framework, and implement the matching/reduction of results in your application code (though this somewhat defeats the "paging" notion if you are fetching all pages for every request).

使用skip进行的查询仍然必须通读中间的索引条目,因此跳过大量文档将不是很有效.

Queries with skip still have to read through the intervening index entries, so skipping a large number of documents will not be very efficient.

您可以考虑通过从上一页的最后一个条目开始进行连续的页面查询,而不是使用跳过偏移量进行分页(即,第一页将是$gte的起始subjectID,随后的页面将是$gt前一页中包含的最后一个subjectID).这将取决于您如何在用户界面中呈现分页-如果您的UI仅选择显示消息的下一页"而不是跳转到特定页面,则使用此方法将是最简单的.

Instead of paging with a skip offset, you could consider doing successive page queries by starting from the last entry of the previous page (i.e. the first page would be $gte the starting subjectID and subsequent pages would be $gt the last subjectID included on the previous page). This will depend on how you present the paging in your user interface - it would be easiest to use this approach if your UI only has the option to show "next" page of messages rather than jumping to a specific page.

这篇关于在mongodb查询中获取项目的索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆