Group By in mongoengine EmbeddedDocumentListField
Asked Answered
P

1

8

Hi so I have this test data in mongo for mongoengine that I use for storing user's cart:

{
    "_id" : ObjectId("55e492ac516ddc17a8b07d2a"),
    "user" : ObjectId("55e3f236516ddc78296968be"),
    "items" : [
        {
            "item" : ObjectId("55e24cd6516ddcbdc081842b"),
            "quantity" : 2,
            "added_date" : ISODate("2015-08-31T17:44:49.023Z")
        },
        {
            "item" : ObjectId("55e24cd6516ddcbdc0818425"),
            "quantity" : 3,
            "added_date" : ISODate("2015-08-31T17:44:49.025Z")
        },
        {
            "item" : ObjectId("55e24cd6516ddcbdc0818420"),
            "quantity" : 3,
            "added_date" : ISODate("2015-08-31T17:44:49.026Z")
        }
    ]
}

Here the models:

class CartItem(mongoengine.EmbeddedDocument):
    item = mongoengine.ReferenceField('Item')
    quantity = mongoengine.IntField()
    added_date = mongoengine.DateTimeField(default=datetime.now())

class Cart(mongoengine.Document):
    user = mongoengine.ReferenceField('User')
    items = mongoengine.EmbeddedDocumentListField(CartItem)

Here I store items in user's cart. Now I would like to get all the unique items in the items list field because there will be duplicate items.

I perform the following queries to get the items:

cart = Cart.objects.filter(user=user).first()
queryset = cart.items

In this case I think I would have to group the items, I tried using raw query in filter : cart.items.filter(__raw__...) But this just doesn't work because raw is not supported in this case. Can someone please help me in how I can do this? Thank you!

Princedom answered 31/8, 2015 at 18:2 Comment(0)
F
5

You can use .distinct() to get all the unique values of items instead of doing groupby.

Return a list of distinct values for a given field.

You need to do something like:

unique_items = Cart.objects.filter(user=user).first().distinct('items')

This will return a list of unique items in a cart for a particular user.

EDIT:

If you want a unique list of item field inside the items embedded document field, then you need to use dot . to go to that field.

Cart.objects.filter(user=user).first().distinct('items.item')
Fley answered 31/8, 2015 at 18:46 Comment(3)
That's great! Thanks! The only thing I changed is .distinct('items.item')Princedom
Glad to help! I have included the same in the ans.Fley
@RahulGupta - How can we sort the result set while making distinct ?Sewoll

© 2022 - 2024 — McMap. All rights reserved.