0

I'm trying to output a Class (from the Classes Model) and its referenced Students--to learn mongoengine and mongodb. The below code gives me the error.

Expected 'pipeline' to be BSON docs (or equivalent), but got []

I'm sure it's something obvious––to those who know mongo and mongoengine. Any help (or push in the right direction) is appreciated :) Thanks in advance

import urllib
from mongoengine import *


connect(db=DB_NAME, username=DB_USER, password=DB_PASSWORD,
        host=DB_URI)

class Students(Document):
    student_id = IntField(unique=True)  
    name = StringField(max_length=50)
    age = IntField(max_length=2)
    gender = StringField(choices=('male', 'female'))


class Classes(Document):
    class_id = IntField(required=True, unique=True)  # 1576407600000
    student_roster = ListField(ReferenceField(Students))


Students.objects.insert([
    Students(name="John", student_id=425736, age=10, gender="male"),
    Students(name="Mary", student_id=114391, age=9, gender="female")
])

Classes(class_id=1576407600000, student_roster=[425736, 114391]).save()


# gives pipeline error
c = Classes.objects.aggregate([
    {'$lookup': {'from': 'students',
            'localField' : 'student_roster',
            'foreignField' : 'student_id',
            'as': 'studentData'
    }
}
])
list(c)
grahama
  • 321
  • 4
  • 13

1 Answers1

0

If I refer to the docs:

class Person(Document):
    name = StringField()

Person(name='John').save()
Person(name='Bob').save()

pipeline = [
    {"$sort" : {"name" : -1}},
    {"$project": {"_id": 0, "name": {"$toUpper": "$name"}}}
    ]
data = Person.objects().aggregate(*pipeline)
assert data == [{'name': 'BOB'}, {'name': 'JOHN'}]

You're using the objects member instead of the objects() one, and you're passing a list where it expects it to be unpacked into dict parameters (the *pipeline, where you put the equivalent of a pipeline)

Er...
  • 526
  • 4
  • 10
  • thanks for the tip :) I'll build upon what you have. I'm coming from SQL and trying to wrap my head around Mongo's 'aggregation/reference' version of relational. In your example, I'll need to assign 'Bob and John' (with uniquely assigned company ids --not mongo's _id) to a Company, That would more closely model my Students in Classes scenario. Thanks for the nudge in the right direction. – grahama Dec 18 '19 at 22:38