I have a two collection that systems and systemsToUsers. It is refer the systems _id as a foreign key system_id in a systemToUsers table. I need system data which all are _id not presents in the sytemToUser table.
I am using the below query but it is taking a long time (5 seconds) for 100 000 data. But need to optimize the query reduce the execution time
db.Systems.aggregate([
{ $lookup: {
from: 'systemsToUsers',
localField: '_id', foreignField: 'system_id',
as: 'systemswithusers' } },
{ $match: { $expr: { $eq: [ { $size: '$systemswithusers' }, 0 ] } } }
]);
Try below $match and make sure every column in aggregate have index.
db.Systems.aggregate([
{
$lookup: {
from: "systemsToUsers",
localField: "_id",
foreignField: "system_id",
as: "systemswithusers"
}
},
{
$match: {
systemswithusers: []
}
}
])
mongoplayground
Related
I have 2 collections I want to combine using lookup.
Collection1: _AddressSyncStatus
fields I wanna use from this collection: "address"
Collection2: EthTokenTransfers
Fields I want to use from this collection: "to_address", "from_address".
Now when I use mongo compass, the lookup filter expects a local field, in my case the local field of EthTokenTransfers to join the collections. My problem now is, that I want to lookup where address from _AddressSyncStatus is either EthTokenTransfers.from_address OR EthTokenTransfers.to_address.
Is this possible using aggregations?
{
from: '_AddressSyncStatus',
localField: 'string', //from_address OR to_address
foreignField: 'address',
as: 'synced_address'
}
One way to do it is using the $lookup pipeline with $or:
db.EthTokenTransfers.aggregate([
{
$lookup: {
from: "_AddressSyncStatus",
let: {
from_address: "$from_address",
to_address: "$to_address"
},
pipeline: [
{
$match: {
$expr: {$or: [{$eq: ["$_id", "$$from_address"]},
{$eq: ["$_id", "$$to_address"]}
]
}
}
}
],
as: "synced_address"
}
}
])
As you can see here.
But I think that for the rset of the work with this data, it will be more convenient like this:
db.EthTokenTransfers.aggregate([
{
$lookup: {
from: "_AddressSyncStatus",
localField: "from_address",
foreignField: "_id",
as: "synced_address_from"
}
},
{
$lookup: {
from: "_AddressSyncStatus",
localField: "to_address",
foreignField: "_id",
as: "synced_address_to"
}
}
])
As you can see here
So I am trying to join two collections together:
Collections are:
shows
episodes
I am using the $lookup value inside the shows collection.
[{$lookup: {
from: 'episode',
localField: 'url',
foreignField: 'show_b',
as: 'match_docs'
}}]
However I am getting all of the episodes from each show inside the match_docs in theory that is fine, however I need to be able to limit it to the latest episode limit:1 for each show ordered by pubDate
If anyone knows how I could limit the match_docs to only lookup once that would be great
I have also tried
{
from: 'episode',
localField: 'url',
foreignField: 'show_b',
pipeline: [
{$sort:{id:1}},{$limit:1},
],
as: 'match_docs'
}
With no success.
That would be easy with the second syntax of $lookup:
[
{
$lookup: {
from: 'episodes', # make sure your collection name is correct
let: {url: '$url'},
pipeline: [
{
$match: {
$expr: {
$eq: ['$show_b', '$$url']
}
}
},
{
$sort: {
pubDate: -1
}
},
{
$limit: 1
}
],
as: 'match_docs'
}
}
]
I Have a collection called "cv" and another collection called "sections"
In the collection "section" I have a field called "ownerCV" which refers to the CV ID
I want to get the CVs which have a minimum of 4 sections
I use
([
{
$lookup: {
from: UserSection.tableName,
localField: '_id',
foreignField: 'ownerCV',
as: 'sections'
}
}, {
$project: {
sectionsCount: {
$size: '$sections'
}
}
}, {
$match: {
'sectionsCount': {
'$gte': 4
}
}
}
])
.skip(count * page)
.limit(count)
.toArray();
But it takes a big time.
So is there another way i can do that in a fast time?
I'm faced into the issue when I'm trying to merge the results of two MongoDB lookup's into one property, and then I want to unwind them and sort.
I have a problem with merging the results of lookup's.
Here is the actual code:
db.getCollection('collectionA').aggregate([
{
$lookup:
{
from: 'collectionB',
localField: "_id",
foreignField: "collectionAKey",
as: "collectionBInfo"
}
},
{
$lookup:
{
from: 'collectionC',
localField: "_id",
foreignField: "collectionAKey",
as: "collectionCInfo"
}
},
/// then I just want to create one property from both of lookup's, unwind them and sort by the timestamp
{
$unwind: "$mergedCollectionsAandB"
},
{
$sort: {
"mergedCollectionsAandB.timestamp": -1
}
}
])
Here is a models of collections:
CollectionA
_id
name
CollectionB
_id
timestamp
collectionAKey
CollectionC
_id
timestamp
collectionAKey
I assume that it's possible by using $mergeObjects MongoDB operator, but I'm stuck a little bit how to do it in a right way. Is that possible? Thanks in advance.
So the final version of my query looks like that, it's what I was looking for:
db.getCollection('collectionA').aggregate([
{
$lookup:
{
from: 'collectionB',
localField: "_id",
foreignField: "collectionAKey",
as: "collectionBInfo"
}
},
{
$lookup:
{
from: 'collectionC',
localField: "_id",
foreignField: "collectionAKey",
as: "collectionCInfo"
}
},
{
$project: {
"mergedCollectionsAandB": { $concatArrays: ["$collectionBInfo", "$collectionCInfo"] }
}
},
{
$unwind: "$mergedCollectionsAandB"
},
{
$sort: {
"mergedCollectionsAandB.timestamp": -1
}
}
])
Aggregate1:
db.collection.aggregate([
{
$lookup: {
...
}
},
{
$limit: 1
}
])
Aggregate2:
db.collection.aggregate([
{
$limit: 1
},
{
$lookup: {
...
}
}
])
Aggregate1 and Aggregate2 are different?
In Aggregate1,is the whole collection scanned firstly, then do $lookup?
If it is different,how to lookup with some query?just like this:
db.collection.aggregate([
{
$lookup: {
from: 'collection2',
localField: 'field',
foreignField: 'field',
as: 'newField',
// do some query when lookup
query: {'newField.xxx': 1}
}
}
])
I know, i can do this:
db.collection.aggregate([
{
$lookup: {
from: 'collection2',
localField: 'field',
foreignField: 'field',
as: 'newField'
}
},
{$unwind: '$newField'},
{$match: {'newField.xxx': 1}}
])
But I'm afraid that, like the example above, the entire collection will be scanned。
Look forward to your reply!
Now,i find this api:$graphLookup.restrictSearchWithMatch,but:
NOTE
You cannot use any aggregation expression in this filter.
For example, a query document such as
{ lastName: { $ne: "$lastName" } }
will not work in this context to find documents in which the lastName
value is different from the lastName value of the input document,
because "$lastName" will act as a string literal, not a field path.