Я бы сказал, что вместо двух .find()
вызовов плюс итерация и затем третий вызов для записи данных, попробуйте этот запрос:
db.col1.aggregate([
{
$lookup: {
from: "col2",
let: { id: "$id", mobileNo: "$mobileNo" },
pipeline: [
{
$match: { $expr: { $and: [ { $eq: [ "$id", "$$id" ] }, { $gte: [ "$mobileNo", "$$mobileNo" ] } ] } }
},
{ $project: { _id: 1 } } // limiting to `_id` as we don't need entire doc of `col2` - just need to see whether a ref exists or not
],
as: "data"
}
},
{ $match: { data: [] } // Filtering leaves docs in `col1` which has no match in `col2`
},
{ $project: { data: 0, _id: 0 } }
])
Тест: mongoplayground
Подробности: Из приведенного выше запроса вы получаете возможность указать условия в $ lookup , чтобы получить документы из col1
, которые имеют ссылку в col2
. Допустим, $lookup
будет выполняться для каждого документа col1
. Таким образом, уникальная комбинация id & mobileNo
из текущего документа в col1
имеет совпадение в col2
, тогда col2
do c '_id
будет помещен в массив data
, в конце то, что мы получим из col1
, будет data: []
, чтобы сказать, что не найдено подходящих документов для этих col1
do c. Теперь вы можете просто записать все возвращенные документы в col2
, используя .insertMany()
. На самом деле вы можете сделать все это, используя $ merge в версии MongoDB> 4.2
без необходимости второго вызова записи (.insertMany()
).
Для вашего сценария в версии MongoDB> 4.2
что-то вроде этого объединит документы во вторую коллекцию:
{ $merge: 'col2' } // Has to be final stage in aggregation
Примечание: Если это нужно делать периодически - независимо от того, как вы это делаете, постарайтесь минимизировать данные, которые вы Вы работаете, возможно, сохраняете поле времени, и вы можете использовать это поле, чтобы сначала отфильтровать документы и выполнить эту работу, или вы также можете воспользоваться _id
, чтобы сказать, что мы сделали для всех этих документов в последнем запуске, и мы нужно начинать с этой документации - это поможет вам значительно сократить объем обрабатываемых данных. Кроме того, не забудьте сохранить индексы.