MongoDB 是否提供了查找或查询方法来测试某个项是否基于任何字段值存在?我们只是想检查存在,而不是返回项目的全部内容。
因为不需要计数,所以应该确保查询在找到第一个匹配项后返回。因为 计数性能不理想,这是相当重要的。下面的查询应该实现这一点:
db.Collection.find({ /* criteria */}).limit(1).size();
请注意,在默认情况下,find().count()支持 limit子句,因此可能返回意外的结果(并尝试查找所有匹配项)。size()或 count(true)将授予限制旗。
find().count()
limit
size()
count(true)
如果您想走极端,您应该确保您的查询使用 备兑指数。覆盖索引只能访问索引,但它们要求对查询的字段进行索引。通常,这样做是因为 count()显然不返回任何字段。不过,覆盖索引有时需要相当冗长的游标:
count()
db.values.find({"value" : 3553}, {"_id": 0, "value" : 1}).limit(1).explain(); { // ... "cursor" : "BtreeCursor value_1", "indexOnly" : true, // covered! }
不幸的是,count()不提供 explain(),所以它是否值得很难说。通常情况下,测量比理论更好,但理论至少可以把你从更大的问题中解救出来。
explain()
我不相信有一个直接的方法来检查项目的价值的存在。但是您可以通过仅检索 id (与领域选择)来实现这一点
db.your_collection.find({..criteria..}, {"_id" : 1});
使用 find () + limit ()会快得多,因为 findOne () 如果文档存在,则始终读取 + 返回 返回游标(或不返回) ,并且只在迭代时读取数据 通过光标。
db.collection.find({_id: "myId"}, {_id: 1}).limit(1)
(而不是 db.collection.findOne({_id: "myId"}, {_id: 1}))。
db.collection.findOne({_id: "myId"}, {_id: 1})
看更多细节: 检查文档是否存在-MongoDB 缓慢的 findOne vs find
如果你使用 Java 和 Spring,你可以使用:
public interface UserRepository extends MongoRepository<User, ObjectId> { boolean existsByUsername(String username); }
对我有用。
从 Mongo 2.6 开始,count有一个 limit可选参数,这使得它成为查找文档是否存在的可行替代方案:
Mongo 2.6
count
db.collection.count({}, { limit: 1 }) // returns 1 if exists and 0 otherwise
或使用过滤查询:
db.collection.count({/* criteria */}, { limit: 1 })
限制匹配出现的次数会使集合扫描在每次找到匹配时停止,而不是遍历整个集合。
从 Mongo 4.0.3 开始,因为 count()是 被认为是不赞成的,我们可以用 countDocuments代替:
Mongo 4.0.3
countDocuments
db.collection.countDocuments({}, { limit: 1 })
db.collection.countDocuments({/* criteria */}, { limit: 1 })
我只使用了 loash 框架-_ isEmpty () ;
const { MongoClient, ObjectId } = require('mongodb'); const _ = require('lodash'); MongoClient.connect(testURL, { useNewUrlParser: true }, (err, client) => { let db = client.db('mycompany'); if (err) { console.log('unable to connect to the mycompany database'); } else { console.log('test connection to the database'); }; db.collection('employee').find({ name: 'Test User' }).toArray((err, result) => { if (err) { console.log('The search errored'); } else if (_.isEmpty(result)) { console.log('record not found') } else { console.log(result); }; }); client.close(); });
泽维尔的最新回答是:
现在希望将回调作为第二个参数,因此可以使用以下方法:
db.collection.countDocuments({}).limit(1)
我目前正在使用这样的东西:
async check(query) { const projection = { _id: 1 }; return !!db.collection.findOne(query, projection); }
它将返回 true 或 false,当然对于最小的数据传输只返回 _ id: 1。
filter_dict = {"key":value} if db.collection.count_documents(filter_dict): print("item is existed") else: print("item is not existed")
我很惊讶地发现 $exists 接线员在这里没有被提及。
$exists
db.collection.findOne({myFieldName: {$exists: 1}})
如果您想要相反的结果(找到一个字段不存在的字段) : db.collection.findOne({myFieldName: {$exists: 0}})
db.collection.findOne({myFieldName: {$exists: 0}})
如果你想得到一个光标,使用 find()代替 findOne(),你可以用 db.collection.find({myFieldName: {$exists: 1}}).isExhausted()得到一个布尔值
find()
findOne()
db.collection.find({myFieldName: {$exists: 1}}).isExhausted()
请注意,isExhausted()只是 蒙哥贝壳法蒙哥贝壳法
isExhausted()