Подтвердить что ты не робот

Как запросить MongoDB, чтобы проверить, существует ли элемент?

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

4b9b3361

Ответ 1

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

db.your_collection.find({..criteria..}, {"_id" : 1});

Ответ 2

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

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

Ответ 3

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

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

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

Посмотрите на более подробную информацию: Проверка наличия документа - MongoDB slow findOne vs find

Ответ 4

Начиная с 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 })

Ответ 5

Я просто использовал фреймворк lodash - _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();
});

Ответ 6

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

public interface UserRepository extends MongoRepository<User, ObjectId> {

    boolean existsByUsername(String username);

}

Меня устраивает.