Как запросить MongoDB, чтобы проверить, существует ли элемент? - PullRequest
32 голосов
/ 05 декабря 2011

Предлагает ли MongoDB метод поиска или запроса, чтобы проверить, существует ли элемент на основе какого-либо значения поля? Мы просто хотим проверить существование, а не возвращать полное содержимое элемента.

Ответы [ 6 ]

53 голосов
/ 05 декабря 2011

Так как вам не нужен счетчик, вы должны убедиться, что запрос вернется после того, как будет найдено первое совпадение.Поскольку производительность count не идеальна , это довольно важно.Следующий запрос должен выполнить это:

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(), поэтому трудно сказать, стоит ли это того или нет.Как обычно, измерение - лучший компаньон, чем теория, но теория может, по крайней мере, избавить вас от более серьезных проблем.

27 голосов
/ 05 декабря 2011

Я не верю, что существует прямой способ проверить наличие предмета по его стоимости. Но вы можете сделать это, просто получив только идентификатор ( с выбором поля )

db.your_collection.find({..criteria..}, {"_id" : 1});
13 голосов
/ 13 октября 2015

Значительно быстрее использовать find () + limit (), потому что findOne () всегда будет читать + возвращать документ, если он существует.find () просто возвращает курсор (или нет) и считывает данные, только если вы перебираете курсор.

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

(вместо db.collection.findOne({_id: "myId"}, {_id: 1})).

Посмотрите на более подробную информацию: Проверка, существует ли документ - MongoDB медленный findOne vs find

8 голосов
/ 26 октября 2018

Начиная с 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 })
0 голосов
/ 16 декабря 2018

Я просто использовал lodash framework - _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 ();

});

0 голосов
/ 01 февраля 2018

Если вы используете Java и Spring, вы можете использовать это:

public interface UserRepository extends MongoRepository<User, ObjectId> {

    boolean existsByUsername(String username);

}

Это работает для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...