Question

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
Was it helpful?

Solution 2

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.

OTHER TIPS

Just to mention all the options. @Ross is right. Mongodb doesn't have joins. But actually you have 2 options (not only one):

  1. (described by @Ross)

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.

  1. 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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top