【问题标题】:Given a list of ids, what's the best way to query which ids do not exist in the collection?给定一个 id 列表,查询集合中不存在哪些 id 的最佳方法是什么?
【发布时间】:2015-07-27 20:50:06
【问题描述】:

我有一组包含唯一 id 字段的文档。现在我有一个 id 列表,其中可能包含一些集合中不存在的 id。从列表中找出这些 id 的最佳方法是什么?

我知道我可以使用 $in 运算符来获取列表中包含 id 的文档,然后与给定的 id 列表进行比较,但是有更好的方法吗?

【问题讨论】:

    标签: javascript mongodb aggregation-framework


    【解决方案1】:

    我想您的收藏中有以下文档:

    { "_id" : ObjectId("55b725fd7279ca22edb618bb"), "id" : 1 }
    { "_id" : ObjectId("55b725fd7279ca22edb618bc"), "id" : 2 }
    { "_id" : ObjectId("55b725fd7279ca22edb618bd"), "id" : 3 }
    { "_id" : ObjectId("55b725fd7279ca22edb618be"), "id" : 4 }
    { "_id" : ObjectId("55b725fd7279ca22edb618bf"), "id" : 5 }
    { "_id" : ObjectId("55b725fd7279ca22edb618c0"), "id" : 6 }
    

    以及以下id列表

    var listId = [ 1, 3, 7, 9, 8, 35 ];
    

    我们可以使用.filter 方法返回不在您的集合中的ids 数组。

    var result = listId.filter(function(el){
        return db.collection.distinct('id').indexOf(el) == -1; });
    

    这会产生

    [ 7, 9, 8, 35 ] 
    

    现在您还可以使用aggregation frameworks$setDifference 运算符。

    db.collection.aggregate([
       { "$group": { "_id": null, "ids": { "$addToSet": "$id" }}}, 
       { "$project" : { "missingIds": { "$setDifference": [ listId, "$ids" ]}, "_id": 0 }}
    ])
    

    这会产生:

    { "missingIds" : [ 7, 9, 8, 35 ] }
    

    【讨论】:

      【解决方案2】:

      不幸的是,MongoDB 只能使用内置函数(否则我建议使用 set),但您可以尝试在列表中找到所有不同的 id,然后手动将它们拉出。

      类似的东西(未经测试):

      var your_unique_ids = ["present", "not_present"];
      
      var present_ids = db.getCollection('your_col').distinct('unique_field', {unique_field: {$in: your_unique_ids}});
      
      for (var i=0; i < your_unique_ids.length; i++) {
          var some_id = your_unique_ids[i];
          if (present_ids.indexOf(some_id) < 0) {
              print(some_id);
          }
      }
      

      【讨论】:

      • 谢谢伊万。根据我的测试,使用 distinct 比使用 $in 运算符快约 50%。我会等待一段时间,看看是否有更好的解决方案弹出,如果没有,您的答案将被接受。
      【解决方案3】:

      以下查询将为您获取结果:

      var listid = [1,2,3,4];
      
      db.collection.aggregate([
       {$project: { uniqueId : 
         {
          "$setDifference": 
              [ listid , db.collection.distinct( "unique_field" )]} , _id : 0 }
         }, 
       {$limit:1}
      ]);
      

      【讨论】:

        猜你喜欢
        • 2015-06-26
        • 1970-01-01
        • 1970-01-01
        • 2023-01-21
        • 2018-03-04
        • 2010-10-10
        • 2016-01-15
        • 1970-01-01
        • 2017-03-16
        相关资源
        最近更新 更多