Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java MongoDB恢复旧查询或跳到文档_Java_Mongodb_Mongodb Query_Mongodb Java - Fatal编程技术网

Java MongoDB恢复旧查询或跳到文档

Java MongoDB恢复旧查询或跳到文档,java,mongodb,mongodb-query,mongodb-java,Java,Mongodb,Mongodb Query,Mongodb Java,我正在开发一个系统,在这个系统中,用户可以使用许多参数查询我的MongoDB数据库。当用户查询时,他们得到20个结果。然而,用户可能希望获得额外的20个结果,然后是另一个,等等 在编写这样一个系统时,我的第一反应是使用“跳过”功能,并跳过返回给用户的结果数;但是,问题是,在用户运行新查询以获得新结果所需的时间内,许多(数百或数千)与用户查询匹配的新文档可能已添加到MongoDB。 因此,“跳过”不会恢复查询最后一次发出的位置 例如 我们在20号文件处出发。用户的下一个查询说跳过20。但是,增加了

我正在开发一个系统,在这个系统中,用户可以使用许多参数查询我的MongoDB数据库。当用户查询时,他们得到20个结果。然而,用户可能希望获得额外的20个结果,然后是另一个,等等

在编写这样一个系统时,我的第一反应是使用“跳过”功能,并跳过返回给用户的结果数;但是,问题是,在用户运行新查询以获得新结果所需的时间内,许多(数百或数千)与用户查询匹配的新文档可能已添加到MongoDB。 因此,“跳过”不会恢复查询最后一次发出的位置

例如

我们在20号文件处出发。用户的下一个查询说跳过20。但是,增加了500份新文件。现在跳过应该是520,以便在最后一次发出的位置拾取查询。但是,我目前无法跟踪自用户上次查询以来添加了多少文档

我的下一个想法是让用户提交上次查询中收到的最后一个文档的Id,以及用户在所有查询中收到的文档总数。我会告诉MongoDB“跳过”用户收到的文档总数-1。然后,我会将每个文档与用户发送的文档的Id进行比较,直到找到用户停止的地方

例如:

public static String getDocument(String lastId, int skip, BasicDBObject query)
{
   DBCursor cursor = collection.find(query).skip(skip);
   while(cursor.hasNext())
   {
      BasicDBObject obj = (BasicDBObject) cursor.next();
      String id = obj.getString("id");
      if(id.equals(lastId))
      {
         //Then we know that here is where we left off, and to start getting new documents
      }
    }
}
我认为,如果添加了许多新文档,这将是低效的,并且可能会使查询时间变慢。这种假设正确吗


有没有办法查询MongoDB,告诉它跳过给定文档Id之前的所有结果?如果没有,是否有处理此类问题的标准方法?我不知该怎么办

问得好。我不知道您为什么在这里提到“聚合”,从您的示例中我看到它是一个mongo常规查询,所以我假设您的问题是关于mongo查询,而不是聚合框架

为了回答你的问题(至少据我所知),首先我想在这里提供一些“提示和技巧”之类的信息

在mongo db中,有更多的理由避免跳过大量对象,这是因为当您使用“跳过X”查询时,引擎必须在到达对象X之前迭代所有X对象(线性扫描)。 因此,如果检索200个对象并使用skip,则获取这200个对象的时间将随着skip值的增加而逐渐增加

这不是mongo独有的,顺便说一句,在关系数据库中也会出现这种情况

在这一领域使用Mongo的一种首选方法是,通过一些您不关心但有索引的内容(例如_id)返回有序的结果

请注意,从查询中,您只对整个结果组进行迭代,并不真正关心这些结果的顺序。 因此,在这种情况下,您可以做的是:

getNResults ordered by id (ascending)
while(shouldRetrieveMoreResults()) {
    memorize the last id in the list of retrieved results
    instead of skip, use the following query: "get 200 objects ordered by id  ascending where id > _a_memorized_id"
    memorize the last id among retrieved ids and perform the loop again and again
}
因为_id上总是有一个索引,所以查询速度会很快,对于较大的跳过值会更有效

这是mongo db书中写的,顺便说一句:)

现在你在这里提出的是另一个问题。基本上你说你有不断变化的数据。 在这种情况下,最好是向文档中添加一些“辅助”字段—一个总是会增加的字段,如时间,这样您就可以按时间对值进行迭代。时间可以被索引。因此,您可能希望使用与我上面描述的相同的技巧,但不是使用按对象id排序,而是使用按另一个索引字段排序

希望这有帮助

getNResults ordered by id (ascending)
while(shouldRetrieveMoreResults()) {
    memorize the last id in the list of retrieved results
    instead of skip, use the following query: "get 200 objects ordered by id  ascending where id > _a_memorized_id"
    memorize the last id among retrieved ids and perform the loop again and again
}