Reputation: 1356
So basically I have these documents
class Tag(Document):
name = StringField()
...
class Doc(Doument):
nameTag = ReferenceField(Tag)
tags = ListField(ReferenceField(Tag))
And I want to query for nameTags with specific names. So I thought the question was answered here How to perform such filter queries in mongoengine on nested dicts or arrays contained in dict with python?
But when I try the query:
name="Hello"
docs1 = Doc.objects(nameTag__name=name)
docs2 = Doc.objects(tags__name=name)
I get the error
Cannot perform join in mongoDB: nameTag__name
Upvotes: 4
Views: 5686
Reputation: 1865
Just to mention all the options. @Ross is right. Mongodb doesn't have joins. But actually you have 2 options (not only one):
you have todo two queries. One to get the matching Tag and then one to query the Doc collection and find any references to that Tag.
Make an aggregation, mongoengine
supports it:
docs1 = Doc.objects.aggregate(
{"$lookup": {
"from": "tag", # Tag collection database name
"foreignField": "_id", # Primary key of the Tag collection
"localField": "nameTag", # Reference field
"as": "nameTag",
}},
{"$unwind": "nameTag"},
{"$match": {"nameTag.name": name}})
$unwind
is needed because $lookup
returns a list of documents. But in your case it's always one document per list, so you can use this code without a doubt.
Second way seems much more complicated than first. But with first method you have to do 2 queries to database (with second - only one). In some cases the second method would be more efficient.
Upvotes: 2
Reputation: 1220
You can perform joins across two collections with mongodb as your backend by using the native Django ORM itself. As such you don't need to use Mongoengine.
Use the django orm and connect it mongodb using a connector like djongo
Upvotes: 0
Reputation: 18101
Mongodb doesn't have joins, yet your query is trying to query across two collections. In this case you have todo two queries. One to get the matching Tag and then one to query the Doc collection and find any references to that Tag.
Upvotes: 1