Arun Rao
Arun Rao

Reputation: 31

querying with projections in mongoengine

I have defined the following class:

class abc(Document)
    attrib1 = StringField()
    attrib2 = StringField()
    attrib3 = StringField()
    .
    .
    attrib30 = StringField()

I need to get only attrib1, attrib2, attrib3 as json output. How can I do that projection with only 3 attributes from my document?

Here is my query which works for one attribute:

for cur in abc.objects(Q(attrib1='xzy') or Q(attrib2='abc')):
    print(json_util.dumps(cur.attrib1))

Upvotes: 3

Views: 2707

Answers (2)

Abhishake Gupta
Abhishake Gupta

Reputation: 3170

from app.models import myCollection
from mongoengine import connect
connect('MyDBName')
# Fetch the data using projection (only)
data = myCollection.objects(key1='val1', timestamp=datetime(2021, 2, 17, 13, 9, 25)).only('field1', 'field2', 'field3')

# then access the data like below:
print("Data length= %d, Type= %s" %(len(data), type(data)))
print("value = ", data[0].field1)

Responses below:

Data length= 366, Type= <class 'flask_mongoengine.BaseQuerySet'>
value = field1_value

Upvotes: 0

sergiuz
sergiuz

Reputation: 5529

Actually, your are wrong.

You are making a query where results needs to contain attrib1='xyz' or attrib2='abc', but you are returning all fields (attributes).

Before you can fix the projection, the actual query needs to be corrected to use bitwise operators rather than and or or.

To specify only certain fields to be returned from the database you need to specify that in the projection.

abc.objects(Q(attrib1='xzy') | Q(attrib2='abc'))

In MongoEngine you can do that by using only:

   result = abc.objects(Q(attrib1='xzy') | Q(attrib2='abc')).only('attrib1', 'attrib2', 'attrib3')

In this way, result is a queryset which contain results having only those 3 fields. Than you can do what you want with hte result.

What you are doing in here:

print(json_util.dumps(cur.attrib1)),

is that you are accessing the attrib1 of each document, and print it, but actually all documents still have all the fields inside.

Upvotes: 3

Related Questions