Mongoengine: Trying to do a "join" on a ListField(ReferenceField(...)) doesn't raise an exception

Created on 6 Jun 2016  路  5Comments  路  Source: MongoEngine/mongoengine

I have two models, let's say:

class Article(Document):
    title = StringField()
    tags = ListField(StringField())

class Blog(Document):
     articles = ListField(ReferenceField(Article))

I expected that Blog.objects.filter(articles__tags='lemon') would return the list of blogs that have at least one article using the tag _lemon_, but it just returns an empty set.

Is it the expected behaviour or a bug? Could it be supported?

Regards,

(De)Reference Bug

Most helpful comment

Actually, you can perform left outer joins in MongoDB, just using the aggregate pipeline $lookup stage.

All 5 comments

I'm pretty sure this can't be done in ME.

This requires queries in two collections. Joins are MongoDB's shortcoming.

You could do this in two steps (do the join in application logic):

  • get the list of all Articles with lemon tag,
  • for each Article in the list, get the list of Blogs having Article in their articles list

Note that in this example, there is probably only one blog for each article, and you could add a blog field to Article to make this faster (one query). But I suppose your real use case is different, although a workaround could be to add a blogs Listfield to Article.

I'm no expert and you may want to ask on StackOverflow for confirmation if you don't get a definitive answer here.

If my understanding and what I say above is correct, then I agree this would look nice as a ME enhancement, but even if someone was willing to do it and if it was reasonably feasible, it could be argued that this would hide complexity too much and could let the user trigger highly consuming queries without realizing it. In other words, I don't expect this to happen any soon. However, assuming I'm right, MongoEngine should probably trigger a warning (an Exception) rather than failing silently.

I would expect ME to trigger an exception

mongoengine.errors.InvalidQueryError: Cannot perform join in mongoDB

like in this example.

I'm marking this as a bug. I don't think this will be done in ME, but we should throw an exception rather than fail silently.

Actually, you can perform left outer joins in MongoDB, just using the aggregate pipeline $lookup stage.

Agreed Blog.objects.filter(articles__tags='lemon') should raise mongoengine.errors.InvalidQueryError instead of returning an empty list. This is most likely a bug in BaseDocument._lookup_field.

I find the same question,
I solve it like this:

stores = Store.objects(sId='9234894')
Comment.objects(store__in=stores)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ajdas-code picture ajdas-code  路  4Comments

adamlwgriffiths picture adamlwgriffiths  路  4Comments

BenCoDev picture BenCoDev  路  5Comments

ZEROF picture ZEROF  路  4Comments

MateuszBelczowski picture MateuszBelczowski  路  4Comments