У меня есть две коллекции: Logs
и Metadatas
. У них обоих есть hash
полей и application
.
У меня есть массив соответствующих Metadatas
которые, как я прогнозировал, будут выглядеть так:
{ hash: string, application: string }[]
Каждая комбинация { hash, application }
уникальна в этом массиве. Моя цель - найти любые Logs
чья комбинация application
и hash
существует как элемент в этом массиве.
Поэтому мне по сути нужно сделать что-то вроде этого:
Logs.find(
{
application: { $in: <one particular item from the array>},
hash: <the hash from the SAME item from that array>
}
);
Это можно сделать в моем JavaScript, но коллекции могут быть очень большими, и я бы предпочел переложить их непосредственно в MongoDB. Есть ли лучший способ сделать такой запрос?
Я пробовал несколько разных типов агрегации, но не могу найти решение.
Вместо того, чтобы делать один запрос для всего массива, вы можете сделать запрос для каждого элемента, чтобы решить это легко:
const logs = await Promise.all(
metadatas.map(metadata => Logs.findOne(metadata))
)
Количество запросов является линейным по отношению к размеру вашего массива метаданных в памяти, и все запросы выполняются одновременно, поэтому сложность должна быть O(timeOfTheLongestQuery)
Если есть больше журналов, которые могут соответствовать кортежу { application, hash }
, используйте find
вместо findOne
:
const logs = await Promise.all(
metadatas.map(metadata => Logs.find(metadata))
)
Это даст вам 2D массив, который вы можете сгладить:
const logs = flatten(await Promise.all(
metadatas.map(metadata => Logs.find(metadata))
))
Или преобразуйте в Map<application + hash, listOfLogs>
если вам нужно обработать его позже, используя те же данные:
const logs = new Map(await Promise.all(
metadatas.map(async metadata => [
JSON.stringify(metadata), // can use a different stringification strategy here
await Logs.find(metadata)
])
))