如何查询MongoDB以测试项是否存在?

use*_*584 37 find mongodb

MongoDB是否提供查找或查询方法来根据任何字段值测试项目是否存在?我们只想检查存在,而不是返回项目的全部内容.

mne*_*syn 58

由于您不需要计数,因此应确保查询在找到第一个匹配项后返回.由于计数性能不理想,这一点非常重要.以下查询应该完成:

db.Collection.find({ /* criteria */}).limit(1).size();
Run Code Online (Sandbox Code Playgroud)

请注意,find().count()在默认情况下并没有履行limit条款,并可能因此返回意外的结果(和将尽力找到所有的结果).size()count(true)将尊重极限标志.

如果您想要达到极限,则应确保查询使用覆盖的索引.涵盖的索引仅访问索引,但它们要求您查询的字段已编制索引.一般来说,这应该这样做,因为count()显然不会返回任何字段.但是,覆盖的索引有时需要相当冗长的游标:

db.values.find({"value" : 3553}, {"_id": 0, "value" : 1}).limit(1).explain();

{
  // ...
  "cursor" : "BtreeCursor value_1",
  "indexOnly" : true,  // covered!
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,count()没有提供explain(),所以是否值得,很难说.像往常一样,测量是一个比理论更好的伴侣,但理论至少可以让你摆脱更大的问题.

  • 你想要`.count(with_limit_and_skip = True)`.没有名为`.size()`的方法 (7认同)
  • 似乎没有 .size() 方法 (4认同)
  • 是`db.Collection.find({/*criteria*/}).limit(1).size();`同步? (2认同)

Ram*_*Vel 28

我不相信有一种直接的方法来检查物品的存在性.但你可以通过只检索id(带字段选择)来做到这一点

db.your_collection.find({..criteria..}, {"_id" : 1});
Run Code Online (Sandbox Code Playgroud)

  • 我在`find`上使用`findOne` (5认同)

gih*_*uka 14

使用find()+ limit()要快得多,因为如果文件存在,findOne()将始终读取+返回文档.find()只返回一个游标(或不返回),只在迭代游标时才读取数据.

db.collection.find({_id: "myId"}, {_id: 1}).limit(1)

(而不是db.collection.findOne({_id: "myId"}, {_id: 1})).

查看更多详细信息:检查文档是否存在 - MongoDB使findOne vs find变慢

  • `find()` 将始终返回一个游标(即使文档不存在 - 在这种情况下 `hasNext()` 将返回 `false`。 (2认同)

Xav*_*hot 11

启动时Mongo 2.6,count有一个limit可选参数,这使得它成为查找文档是否存在的可行替代方法:

db.collection.count({}, { limit: 1 })
// returns 1 if exists and 0 otherwise
Run Code Online (Sandbox Code Playgroud)

或者使用过滤查询:

db.collection.count({/* criteria */}, { limit: 1 })
Run Code Online (Sandbox Code Playgroud)

限制匹配事件的数量使得只要找到匹配而不是遍历整个集合,集合扫描就会停止.


开始Mongo 4.0.3,因为count()认为已弃用,我们可以使用countDocuments:

db.collection.countDocuments({}, { limit: 1 })
Run Code Online (Sandbox Code Playgroud)

或者使用过滤查询:

db.collection.countDocuments({/* criteria */}, { limit: 1 })
Run Code Online (Sandbox Code Playgroud)