#javascript #node.js #mongodb
#javascript #node.js #mongodb
Вопрос:
Я столкнулся с проблемой поиска пар динамических значений ключа с использованием .find
метода в MongoDB. вот мой массив объектов, пары ключ-значение которых можно увеличить…
[
{
"key" : "dynamicKey1",
"value": "dynamicValue1"
},
{
"key" : "dynamicKey2",
"value": "dynamicValu2"
},
...
]
Я хочу получить результат таким образом, чтобы он удовлетворял всем условиям пары ключ-значение. Что-то вроде поиска всех документов из коллекции, которые удовлетворяют этим условиям.
Итак, мой API таков:
app.post('/search/:name', (req, res) => {
const collectionName = req.params.name;
async.eachSeries(req.body, (item, callback) => {
const database = client.db("databaseName");
const result = database.collection(collectionName).find({ [item.key]: item.value }).toArray();
result.then((doc) => {
res.json(doc)
})
callback();
});
});
результат возвращает два или более обещаний, но в результате мне нужны только те документы, которые удовлетворяют всем .find
запросам.
Как я должен это решить?
Спасибо
Вот изображение запроса Insomnia POST: Insomnia
Комментарии:
1. Не могли бы вы, пожалуйста, объяснить, что на самом деле вы пытаетесь сделать, запрос и возвращаете только один документ немного больше?
2. @kgangadhar да, итак, у меня есть массив объектов с ключами и значениями, ключи и значения могут отличаться при каждом вызове API. поэтому мне нужно получить только те документы из коллекции, которые удовлетворяют всем условиям значения ключа. таким образом, приведенный выше API запускается для каждого объекта пары ключ-значение и возвращает метод объединения всех
.find
. Я хотел бы иметь только один результат, который удовлетворяет всем условиям пары ключ-значение, простым словом, пересечение всех запросов. Я пробовал агрегировать, но не знаю, как правильно его написать.3. Пожалуйста, проверьте изображение, которое я добавил к сообщению
4. Я рекомендую выполнять поиск в MongoDB Atlas с помощью подстановочных путей. Это намного проще, многофункциональнее для варианта использования и быстрее docs.atlas.mongodb.com/reference/atlas-search /…
5. @Nice-Guy я это проверил. Это также полезно. Спасибо 🙂
Ответ №1:
На основе предоставленного вами изображения ваши данные в базе данных имеют следующий формат:
[
{
"_id": "1",
"region": "Auckland",
"anzsic_descriptor":"Agriculture",
"gas": "carbon diaoxide equivalents",
"units":"kilotonnes",
"magnitude":"carbon diaoxide equivalents",
"year": "2011",
"data_val": "764.3"
},
{
"_id": "2",
"region": "Canterbury",
"anzsic_descriptor":"Agriculture",
"gas": "carbon diaoxide equivalents",
"units":"kilotonnes",
"magnitude":"carbon diaoxide equivalents",
"year": "2011",
"data_val": "6823.16"
},
{
"_id": "3",
"region": "Bay of Plenty",
"anzsic_descriptor":"Agriculture",
"gas": "carbon diaoxide equivalents",
"units":"kilotonnes",
"magnitude":"carbon diaoxide equivalents",
"year": "2011",
"data_val": "1477.94"
}
...........
]
Получает /search/:name
тело, представляющее собой массив в приведенном ниже формате:
[{
"key": "year",
"value": "2011"
}, {
"key": "data_val",
"value": "764.3"
}]
Вам необходимо использовать запрос generate следующим образом, чтобы сначала сгенерировать ваш запрос перед запросом к БД:
const generateQuery = (arr) => {
return arr.reduce((result, item) => {
const {key, value } = item;
result[key] = value;
return resu<
}, {});
};
console.log(generateQuery([{"key": "year","value": "2011"},{"key": "data_val","value": "764.3"}]))
Запрос к БД для сгенерированного запроса выглядит следующим образом: mongo playground.
Затем используйте этот сгенерированный запрос, чтобы получить результат в конечной точке, все эти изменения выглядят следующим образом:
const generateQuery = (arr) => {
return arr.reduce((result, item) => {
const { key, value } = item;
result[key] = value;
return resu<
}, {});
};
app.post('/search/:name', (req, res) => {
return new Promise((resolve, reject) => {
const collectionName = req.params.name;
const queryArry = req.body // [{"key": "year","value": "2011"},{"key": "data_val","value": "764.3"}]
const query = generateQuery(queryArry);
const database = client.db("databaseName");
database.collection(collectionName).find(query).then(result => {
return resolve(result);
}).catch(e => {
reject(e);
});
}).catch(e => {
reject(e);
})
});
Комментарии:
1. Правильно, спасибо за помощь 🙂