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

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

140441 次浏览

因为不需要计数,所以应该确保查询在找到第一个匹配项后返回。因为 计数性能不理想,这是相当重要的。下面的查询应该实现这一点:

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

请注意,在默认情况下,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!
}

不幸的是,count()不提供 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}))。

看更多细节: 检查文档是否存在-MongoDB 缓慢的 findOne vs find

如果你使用 Java 和 Spring,你可以使用:

public interface UserRepository extends MongoRepository<User, ObjectId> {


boolean existsByUsername(String username);


}

对我有用。

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

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

或使用过滤查询:

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

限制匹配出现的次数会使集合扫描在每次找到匹配时停止,而不是遍历整个集合。


Mongo 4.0.3 开始,因为 count()被认为是不赞成的,我们可以用 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 })

现在希望将回调作为第二个参数,因此可以使用以下方法:

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 接线员在这里没有被提及。

db.collection.findOne({myFieldName: {$exists: 1}})

如果您想要相反的结果(找到一个字段不存在的字段) : db.collection.findOne({myFieldName: {$exists: 0}})

如果你想得到一个光标,使用 find()代替 findOne(),你可以用 db.collection.find({myFieldName: {$exists: 1}}).isExhausted()得到一个布尔值

请注意,isExhausted()只是 蒙哥贝壳法蒙哥贝壳法