Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot query on _cls #450

Closed
arthurlenoir opened this issue Aug 20, 2013 · 12 comments
Closed

Cannot query on _cls #450

arthurlenoir opened this issue Aug 20, 2013 · 12 comments

Comments

@arthurlenoir
Copy link

Hi,

I needed to build a complex query in which I had to add a predicate on the _cls attribute through a naw query:
query |= Q(raw={'_cls': "My.Sub.Class"})

However, because of the construction of the query with a dict, mongoengine overide this part of the query with:
{ "_cls" : { "$in" : ["Class", "Class.SubClass", "and so on"]}}.

I have been able to get around this problem by adding a $or predicate but I think I should not have to do that:
query |= Q(raw={'$or': [{'_cls': "My.Sub.Class"}]})

Thanks for your great work!

@rozza
Copy link
Contributor

rozza commented Aug 20, 2013

Can you explain your usecase? why you have to use __raw__ at all?

@arthurlenoir
Copy link
Author

Because I cannot regularly query on the _cls field, I cannot do Q(_cls="MyClass").

@rozza
Copy link
Contributor

rozza commented Aug 20, 2013

I guessed that :) but I'm trying to understand what is failing in the Document definition that forces you have to work around with __raw__.

Can you provide an example on why you need to ? Can't you use the inherited classes which automatically inject _cls into the query?

@arthurlenoir
Copy link
Author

Ok, so to explain my usecase: All my users generate Activities. There are several kind of Activities which are all subclasses of the Activity class. Users follow other users and so have all the activities of the user they follow. But they have also all the activities of a certain kind. So I need to make the query: {$or: [{user_id: {$in: [list, of, user, ids]}}, {_cls: "My.Sub.Class"}]}.

@alonho
Copy link
Contributor

alonho commented Aug 22, 2013

+1
This is a duplicate of this:
#397

@rozza
Copy link
Contributor

rozza commented Aug 23, 2013

I agree I think we could make a cls field automatically for inherited documents and auto inject it into the definition then you could do things like: Animal.objects(cls__in=[Dog,Fish])

Scheduling for 0.9

@rochacbruno
Copy link
Contributor

👍 also need this to create filters for content types defined in modules in www.quokkaproject.org, currently I am duplicating that field on .save() method to be able to query.

@Reddine
Copy link

Reddine commented Feb 22, 2015

to query on this field all you need is to set the parameter class_check to False
here is a solution:
http://reddines.blogspot.com/2015/02/how-to-query-on-cls-attribute-on.html

@rochacbruno
Copy link
Contributor

👍 @Reddine

@lafrech
Copy link
Member

lafrech commented Jan 8, 2016

Hi.

@Reddine, is this relevant on MongoEngine 0.10.5?

(The context: I'm trying to use flask-mongoengine/WTForms and Document inheritance, and I'm looking for the best way to filter by subclass.)

class Animal(Document):
    meta = {'allow_inheritance': True}
class Fish(Animal): 
    pass
class Mammal(Animal): 
    pass

The link about query on _cls seems outdated.

Animal.objects(class_check=True, cls__in=['Animal.Mammal.Dog','Animal.Fish'])
Animal.objects(class_check=False, cls__in=['Animal.Mammal.Dog','Animal.Fish'])

both raise

mongoengine.errors.InvalidQueryError: Cannot resolve field "cls"

And

Animal.objects(class_check=True, _cls__in=['Animal.Mammal.Dog','Animal.Fish'])
Animal.objects(class_check=False, _cls__in=['Animal.Mammal.Dog','Animal.Fish'])

return what I expect.

So,

  • It appears I can query on '_cls' whatever the value of class_check. The role of class_check is unclear to me.
  • Unlike what the blog post reads, I need to use '_cls', not 'cls'.

@Reddine
Copy link

Reddine commented Jan 9, 2016

Indeed, I removed the class_check attribute from a query in my application that runs on recent version of mongoengine and I got the same result. using only '_cls'
the blog explains the role of class_check as mentioned in the documentationAPI

@wojcikstefan
Copy link
Member

wojcikstefan commented Mar 5, 2017

Although I'm not in love with the current solution, we can query on _cls now:

In [11]: class Animal(Document):
    ...:     meta = {'allow_inheritance': True}
    ...:
    ...: class Fish(Animal):
    ...:     pass
    ...:
    ...: class Dog(Animal):
    ...:     pass
    ...:

In [12]: Dog.objects.create()
Out[12]: <Dog: Dog object>

In [13]: Fish.objects.create()
Out[13]: <Fish: Fish object>

In [14]: Animal.objects
Out[14]: [<Dog: Dog object>, <Fish: Fish object>]

In [15]: Animal.objects(_cls='Animal.Fish')
Out[15]: [<Fish: Fish object>]

The fix was introduced in #719.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants