Jared Joke
Jared Joke

Reputation: 1356

How to perform a mongoengine query of a nested field?

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

Answers (3)

egvo
egvo

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):

  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.

Upvotes: 2

nesdis
nesdis

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

Ross
Ross

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

Related Questions