MongoDB: узнайте, какой элемент массива запросов отсутствует в базе данных

#arrays #mongodb #find

Вопрос:

можно ли узнать, что элемент массива запросов отсутствует в базе данных?

пример:

 const query = ['aaa','bbb','ccc']
 

Документы в бд:

 [{name:'bbb'},{name:'ccc'}]
 

Я хочу найти элементы массива запросов не в базе данных:
возвращаемый результат должен быть:

 ['aaa']
 

Я не могу найти какой-либо быстрый метод для этого, кроме запроса каждого элемента(или пакета?) в массиве

У кого-нибудь есть лучший метод? Спасибо

Ответ №1:

Запрос на то, что отсутствует, всегда является более дорогостоящей операцией, также нет «волшебного» запроса, чтобы сделать это за вас. Я рекомендую использовать особый метод Монго, вот так:

 const queryArr = ['aaa', 'bbb', 'ccc'];
const allNames = await db.collection.distinct('name');
const notInDb = queryArr.filter(e => !allNames.includes(e));
 

Однако, если вы хотите сделать это с помощью команды 1 db, вы можете сделать что-то вроде этого:

 db.collection.aggregate([
  {
    $group: {
      _id: null,
      names: {
        "$addToSet": "$name"
      }
    }
  },
  {
    "$replaceRoot": {
      "newRoot": {
        results: {
          $filter: {
            input: [
              "aaa",
              "bbb",
              "ccc"
            ],
            as: "datum",
            cond: {
              $not: {
                "$setIsSubset": [
                  [
                    "$datum"
                  ],
                  "$names"
                ]
              }
            }
          }
        }
      }
    }
  }
])
 

Игровая площадка Монго

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

 const queryArr = ['aaa', 'bbb', 'ccc'];

for (let queryName of queryArr) {
    const found = await db.collection.findOne({name: queryName})
    if (!found) {
        //ding
    }
}
 

Предполагая, что у вас есть индекс на name поле, это должно быть очень эффективно.