Я столкнулся с проблемой поиска динамических пар ключ-значение с использованием метода .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
запросам в качестве результата.
Как мне решить эту проблему?
Спасибо
Вот изображение POST-запроса Insomnia: Insomnia
@kgangadhar да, поэтому у меня есть массив объектов с ключами и значениями, ключи и значения могут быть разными при каждом вызове API. поэтому мне нужно получить только те документы из коллекции, которые удовлетворяют всем условиям ключевого значения. поэтому приведенный выше API запускается для каждого объекта пары значений ключа и возвращает объединение всех методов .find
. Я хотел бы иметь только один результат, который удовлетворяет всем условиям пар ключ-значение, проще говоря, пересечение всех запросов. Я пробовал агрегат, но не знаю, как его правильно написать.
Пожалуйста, проверьте изображение, которое я добавил к сообщению
Я рекомендую MongoDB Atlas Search с подстановочными путями. Это намного проще, многофункциональнее и быстрее docs.atlas.mongodb.com/reference/atlas-search/…
@ Nice-Guy Я проверил это. Это также полезно. Спасибо :)
На основе предоставленного вами изображения ваши данные имеют следующий формат в базе данных:
[
{
"_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"
}]
Вам нужно использовать генерацию запроса следующим образом, чтобы сначала сгенерировать запрос перед запросом БД:
const generateQuery = (arr) => {
return arr.reduce((result, item) => {
const {key, value } = item;
result[key] = value;
return result;
}, {});
};
console.info(generateQuery([{"key": "year","value": "2011"},{"key": "data_val","value": "764.3"}]))
Запрос к БД для сгенерированного запроса выглядит так: mongo player.
Затем используйте этот сгенерированный запрос, чтобы получить результат в конечной точке, все эти изменения выглядят так:
const generateQuery = (arr) => {
return arr.reduce((result, item) => {
const { key, value } = item;
result[key] = value;
return result;
}, {});
};
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);
})
});
Правильно, спасибо за помощь :)
Не могли бы вы объяснить, что на самом деле вы пытаетесь сделать, запрос и еще немного вернуть только один документ?