0

I have a document and an embedded document as shown below. And I would like to query the embedded document in mongoengine. In sql, this would be: SELECT A.Nom_PC, B.Intitule from Comptes as A, Vals as B WHERE B.Num = "some value"

class Vals(EmbeddedDocument):
    Num = StringField()
    Intitule = StringField()
    meta = {'allow_inheritance': True}

class Comptes(Document):
    Nom_PC = StringField()
    PC = ListField(EmbeddedDocumentField(Vals))
    meta = {'allow_inheritance': True}

I've tried out some things that didn't work like:

Comptes.objects(Vals__match={ "Num": Num }).aggregate(
       {'$project': {
           'PC': {
               '$filter': {
                   'input': '$PC',
                   'as': 'Vals',
                   'cond': {'$eq': ['$$Vals.Num', Num]}
               }
           }
       }}
   )
salma
  • 13
  • 3

1 Answers1

0

First off, you really should use

PC = EmbeddedDocumentListField(Vals)

instead of

PC = ListField(EmbeddedDocumentField(Vals))

This is because lists of embedded documents require special considerations.

As to the query:

q = Comptes.objects(PC__Num="some value")

This creates a query for all matching Comptes documents. You can then cherry pick whatever data you wish from each document.

(If, in the future, you need to match on multiple items in an EmbeddedDocument, use the match keyword. See the docs for more info.)

For example:

my_list = []
for doc in q:
    for v in doc.PC:
        if v.Num == "some value":
            my_list.append([doc.Nom_PC, v.Intitule])

For a YouTube vid I made with further details about the EmbeddedDocumentListField: https://www.youtube.com/watch?v=ajwPOyb6VEU&index=6

JohnAD
  • 879
  • 6
  • 6
  • If you don't mind me asking another question, I'd also like to insert new values of Num and Intitule at a certain position for example i have an index i that corresponds to the position of specific Vals.Num and Vals.Intitule i want to know how to create that index (cause i think an embedded document doesn't have an id by default) and then how to insert the new values right after that index – salma Oct 09 '18 at 10:47
  • For one particular document that is already loaded into memory, just use standard Python practices. When the structure of a list is altered, the whole list is saved on update. So, for example, if the document is loaded in `d` and a new EmbeddedDocument is `v`, then to insert that entry at index 2, use `d.PC.insert(2, v)`. Then, of course, `d.save()`. – JohnAD Oct 11 '18 at 01:03