How to query MongoDB to test if an item exists?

后端 未结 9 1489
囚心锁ツ
囚心锁ツ 2020-11-27 04:06

Does MongoDB offer a find or query method to test if an item exists based on any field value? We just want check existence, not return the full contents of the item.

相关标签:
9条回答
  • 2020-11-27 04:14

    Starting Mongo 2.6, count has a limit optional parameter, which makes it a viable alternative to find whether a document exists or not:

    db.collection.count({}, { limit: 1 })
    // returns 1 if exists and 0 otherwise
    

    or with a filtering query:

    db.collection.count({/* criteria */}, { limit: 1 })
    

    Limiting the number of matching occurrences makes the collection scan stop whenever a match is found instead of going through the whole collection.


    Starting Mongo 4.0.3, since count() is considered deprecated we can use countDocuments instead:

    db.collection.countDocuments({}, { limit: 1 })
    

    or with a filtering query:

    db.collection.countDocuments({/* criteria */}, { limit: 1 })
    
    0 讨论(0)
  • 2020-11-27 04:19

    Im currently using something like this:

    async check(query) {
      const projection = { _id: 1 };
    
      return !!db.collection.findOne(query, projection);
    }
    

    It will return true or false, of course returning only _id: 1 for smallest data transfer.

    0 讨论(0)
  • 2020-11-27 04:21

    Since you don't need the count, you should make sure the query will return after it found the first match. Since count performance is not ideal, that is rather important. The following query should accomplish that:

    db.Collection.find({ /* criteria */}).limit(1).size();
    

    Note that find().count() by default does not honor the limit clause and might hence return unexpected results (and will try to find all matches). size() or count(true) will honor the limit flag.

    If you want to go to extremes, you should make sure that your query uses covered indexes. Covered indexes only access the index, but they require that the field you query on is indexed. In general, that should do it because a count() obviously does not return any fields. Still, covered indexes sometimes need rather verbose cursors:

    db.values.find({"value" : 3553}, {"_id": 0, "value" : 1}).limit(1).explain();
    
    {
      // ...
      "cursor" : "BtreeCursor value_1",
      "indexOnly" : true,  // covered!
    }
    

    Unfortunately, count() does not offer explain(), so whether it's worth it or not is hard to say. As usual, measurement is a better companion than theory, but theory can at least save you from the bigger problems.

    0 讨论(0)
  • 2020-11-27 04:23

    An update to Xavier's answer:

    db.collection.countDocuments({}, { limit: 1 })
    

    Expects a callback as a second argument now, so this can be used instead:

    db.collection.countDocuments({}).limit(1)
    
    0 讨论(0)
  • 2020-11-27 04:24

    If you use Java and Spring you can use that:

    public interface UserRepository extends MongoRepository<User, ObjectId> {
    
        boolean existsByUsername(String username);
    
    }
    

    It works for me.

    0 讨论(0)
  • 2020-11-27 04:25
    filter_dict = {"key":value}
    if db.collection.count_documents(filter_dict):
        print("item is existed")
    else:
        print("item is not existed")
    
    0 讨论(0)
提交回复
热议问题