2013-03-28 4 views
2

Я пытаюсь воспроизвести следующий запрос в python с использованием MongoEngine без особого успеха.MongoEngine: позиционная проекция массива во встроенный документ

Оригинальный источник данных и запрос: http://docs.mongodb.org/manual/reference/projection/positional/#prj._S_

Запрос в основном возвращает первый элемент согласованный во встроенном документе, а не сам весь встроенный Задокументировать.

Мой код:

from mongoengine import * 
connect('test') 


class Student(Document): 
    semester = IntField() 
    grades = ListField(EmbeddedDocumentField('Grade')) 


class Grade(EmbeddedDocument): 
    value = FloatField() 

    def __str__(self): 
     return "%s" % self.value 

student_1 = Student(semester=1, grades=[Grade(value=70), Grade(value=87), Grade(value=90)]).save() 
student_2 = Student(semester=1, grades=[Grade(value=90), Grade(value=88), Grade(value=92)]).save() 

result = Student.objects(semester=1, grades__value__gte=85).only("grades.$") 

for r in result: 
    print r.grades 

Когда я делаю это, я получаю сообщение об ошибке:

Traceback (most recent call last): 
    File "test_me_so.py", line 21, in <module> 
    result = Student.objects(semester=1, grades__value__gte=85).only("grades.$") 
    File "/.../lib/python2.7/site-packages/mongoengine/queryset.py", line 1225, in only 
    return self.fields(**fields) 
    File "/.../lib/python2.7/site-packages/mongoengine/queryset.py", line 1271, in fields 
    fields = self._fields_to_dbfields(fields) 
    File "/.../lib/python2.7/site-packages/mongoengine/queryset.py", line 1289, in _fields_to_dbfields 
    field = ".".join(f.db_field for f in QuerySet._lookup_field(self._document, field.split('.'))) 
    File "/.../lib/python2.7/site-packages/mongoengine/queryset.py", line 1289, in <genexpr> 
    field = ".".join(f.db_field for f in QuerySet._lookup_field(self._document, field.split('.'))) 
AttributeError: 'str' object has no attribute 'db_field' 

Любая помощь будет высоко ценится!

ответ

0

Я не уверен в синтаксисе mongoengine, но я думаю, что вам не нужен бит «только».

Индикатор $ positional обычно захватывает релевантные значения из массива, и похоже, что он будет задействован.

0

positional operator предназначен для обновления первого элемента внутри массива, соответствующего вашему запросу.

Язык запросов касается поиска документов, и в настоящее время вы не можете фильтровать массив внутри документа. Вы можете срезать и возвращать подмножество массива, но не только возвращать сопоставленное подмножество.

Так что в этом случае вам придется отфильтровать оценки в python и как часть цикла.

Альтернативной стратегией может быть использование aggregation framework для $ разматывать массив и $ match, а затем перестраивать массив grades - но это не встроено в mongoengine в это время.

+0

Благодарим за отзыв. Но mongodb [doc] (http://docs.mongodb.org/manual/reference/projection/positional/) утверждает, что оператор позиционирования предназначен для выбора данных, а также для обновления данных. Я закончил этот запрос в mongodb напрямую. – ducky

Смежные вопросы