#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
поле, это должно быть очень эффективно.