【问题标题】:Get position of selected document in collection [mongoDB]获取所选文档在集合中的位置 [mongoDB]
【发布时间】:2012-06-04 13:08:59
【问题描述】:

如何获取所选文档在 mongo 集合中的位置(索引)?

例如 本文档:db.myCollection.find({"id":12345})myCollection 中有索引3

myCollection:
    id: 12340, name: 'G'
    id: 12343, name: 'V'
    id: 12345, name: 'A'
    id: 12348, name: 'N'

【问题讨论】:

    标签: mongodb collections find position


    【解决方案1】:

    如果您的要求是查找文档的位置而不考虑任何顺序,那不是 可能,因为 MongoDb 不按特定顺序存储文档。 但是,如果你想知道基于某个字段的索引,比如_id,你可以使用这种方法。

    如果您严格遵循 _id 字段中的自动增量。您可以计算所有文件 值小于 _id 的值,比如 n ,那么 n + 1 将是基于 _id 的文档索引。

    n = db.myCollection.find({"id": { "$lt" : 12345}}).count() ;
    

    如果从集合中删除文档,这也是有效的。

    【讨论】:

    • 我个人使用这个db.collection.find({_id: {$lte: ObjectId("12345")}}).count() 命令来获取位置......我的意思是小于等于更具体。
    【解决方案2】:

    据我所知,没有单一的命令可以做到这一点,这在一般情况下是不可能的(参见 Derick 的回答)。但是,使用count() 对有序 id 值字段进行查询似乎有效。 警告:假设存在一个可靠排序的字段,这在并发编写器的情况下很难实现。在此示例中使用了_id,但这仅适用于单个编写器案例。

    MongoDB shell version: 2.0.1
    connecting to: test
    > use so_test
    switched to db so_test
    > db.example.insert({name: 'A'})
    > db.example.insert({name: 'B'})
    > db.example.insert({name: 'C'})
    > db.example.insert({name: 'D'})
    > db.example.insert({name: 'E'})
    > db.example.insert({name: 'F'})
    > db.example.find()
    { "_id" : ObjectId("4fc5f040fb359c680edf1a7b"), "name" : "A" }
    { "_id" : ObjectId("4fc5f046fb359c680edf1a7c"), "name" : "B" }
    { "_id" : ObjectId("4fc5f04afb359c680edf1a7d"), "name" : "C" }
    { "_id" : ObjectId("4fc5f04dfb359c680edf1a7e"), "name" : "D" }
    { "_id" : ObjectId("4fc5f050fb359c680edf1a7f"), "name" : "E" }
    { "_id" : ObjectId("4fc5f053fb359c680edf1a80"), "name" : "F" }
    > db.example.find({_id: ObjectId("4fc5f050fb359c680edf1a7f")})
    { "_id" : ObjectId("4fc5f050fb359c680edf1a7f"), "name" : "E" }
    > db.example.find({_id: {$lte: ObjectId("4fc5f050fb359c680edf1a7f")}}).count()
    5
    > 
    

    如果查询的字段被索引,这也应该相当快。该示例在 mongo shell 中,但 count() 也应该在所有驱动程序库中都可用。

    【讨论】:

      【解决方案3】:

      这可能是一种非常缓慢但直接的方法。在这里你可以像往常一样传递查询。只是我正在循环所有文档并检查条件是否匹配记录。在这里,我正在检查 _id 字段。您可以使用任何其他单个字段或多个字段来检查它。

      var docIndex = 0;
      db.url_list.find({},{"_id":1}).forEach(function(doc){
        docIndex++;
        if("5801ed58a8242ba30e8b46fa"==doc["_id"]){
          print('document position is...' + docIndex);
          return false;
        }
      });
      

      【讨论】:

      • 这不是问题的答案,但它解决了我的问题..Thanx
      • 这是答案,也是唯一对我有用的答案。
      【解决方案4】:

      MongoDB 无法返回此值,因为它不会像 MySQL f.e. 一样在数据库中保持文档的顺序。不命名行号。

      jhonkola 的 ObjectID 技巧只有在只有一个客户端创建新元素时才有效,因为 ObjectID 是在客户端生成的,第一部分是时间戳。如果不同的客户端与同一台服务器通信,则无法保证顺序。不过,我不会依赖这个。

      我也不太明白你想要做什么,所以也许在你的问题中提到这一点?然后我可以更新答案。

      【讨论】:

      • 感谢告知_id问题,已修改答案。
      • 我有同样的要求,在我的情况下,我需要知道用户的位置排序,如果用户在位置 13,500,从 13,450 到 13,550,所以用户有关于他的排名的一些背景。此外,count 解决方案对于排名较低的解决方案非常慢,因为如您所知,count 将必须遍历与查询匹配的所有文档,如果我的集合按分数排序,我有 10,000,000 个用户,并且需要获得第 9,999,500 个用户的位置,它实际上必须计算所有集合。有没有人有其他想法?
      • @jmdiego,你有没有为你描述的问题找到一个可行的解决方案?我需要有基于光标的结果的位置。
      • 只需查询所有大于或小于您的值的结果,并计算它。
      【解决方案5】:

      重组您的集合以包含任何条目的位置,即 {'id': 12340, 'name': 'G', 'position': 1} 然后在搜索数据库集合(myCollection)时使用所需的位置作为查询

      【讨论】:

        【解决方案6】:

        我使用的返回整个集合的查询都使用排序来获得可重现的顺序,find.sort.forEach 与上面的脚本一起使用以获取正确的索引。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多