2013-11-28 3 views
0

Я хочу знать, как использовать MongoAlchemy о встраиваемой операции docment. Но я не нашел об этом никаких документов. Может ли кто-нибудь мне помочь?MongoAlchemy запрос вложенных документов

Вот демонстрационный код:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

from flask import Flask 
from flaskext.mongoalchemy import MongoAlchemy 

app = Flask(__name__) 
app.config['DEBUG'] = True 
app.config['MONGOALCHEMY_DATABASE'] = 'book' 
db = MongoAlchemy(app) 

class Comment(db.Document): 
    user_id = db.StringField(db_field='uid') 
    posted = db.StringField(db_field='posted') 

class Book(db.Document): 
    title = db.StringField() 
    author = db.StringField() 

    comments = db.ListField(db.DocumentField(Comment), db_field='Comments') 

from mongoalchemy.session import Session 
def test(): 
    with Session.connect('book') as s: 
     s.clear_collection(Book) 

    save() 
    test_Book() 

def save(): 
    title = "Hello World" 
    author = 'me' 

    comment_a = Comment(user_id='user_a', posted='post_a') 
    comment_b = Comment(user_id='user_b', posted='post_b') 
    comments = [comment_a, comment_b] 

    book = Book(title=title, author=author, comments=comments) 
    book.save() 

def test_Book(): 
    book = Book.query.filter({'author':'me'}).first() 
    comment = book.comments[0] 
    comment.posted = str(book.comments[0].posted)+'_new' 
    book.save() 
    print 'change posted: Book.comments[0].posted:', book.comments[0].posted 

    comment_c = Comment(user_id='user_c', posted='post_c') 
    book.comments.append(comment_c) 
    book.save() 
    print 'append: Book.comments[2].posted:', book.comments[2].posted 

    query = Book.query.filter({Book.comments:{'$elemMatch':{Comment.user_id:'user_c'}}}).limit(1).first() 
    print 'query type:', type(query) 

if __name__ == '__main__': 
    test() 
  1. Я хочу запросить данные, которые user_id является «Пользователь С», а просто вернуться назад на один комментарий, как я могу это сделать? Есть ли эти методы ниже MongoAlchemy? Кстати, эти методы вернут весь документ.

    #query = Book.query.filter({Book.comments:{'uid':'user_c'}}).limit(1).first() 
    #query = Book.query_class(Comment).filter(Comment.user_id == 'user_c').limit(1).first() 
    #query = Book.query.filter({'comments':{'$elemMatch':{'uid':'user_c'}}}).limit(1).first() 
    #query = Book.query.filter({Book.comments:{'$elemMatch':{Comment.user_id:'user_c'}}}).limit(1).first() 
    
  2. Как я могу изменить «на» пользователя C «user_c_new», которые находят по запросу?

  3. Как удалить один комментарий, который user_id является «user_b»?

ответ

1

Mongo не поддерживает возвратные поддокументы. Вы можете использовать $ elemMatch для фильтрации, чтобы возвращать только документы с соответствующими атрибутами, но вы должны сами взять комментарии. Вы могли бы немного оптимизировать лишь возвращение в поле для комментариев следующим образом:

query = Book.query.filter({Book.comments:{'$elemMatch':{Comment.user_id:'user_c'}}}) 
query = query.fields(Book.comments.elem_match({Comment.user_id:'user_c'})) 
result = query.limit(1).first() 
print 'query result:', result.comments 

Обратите внимание, что там не была ошибка с этим вплоть до 0.14.3 (который я только что выпустил несколько минут назад), которое вызвало бы results.comments не работать.

Другое Очень важное примечание заключается в том, что элемент elem_match, который я делаю, возвращает только первый соответствующий элемент. Если вы хотите, чтобы все элементы соответствовали, вы должны отфильтровать их самостоятельно:

query = Book.query.filter({Book.comments:{'$elemMatch':{Comment.user_id:'user_c'}}}) 
result = query.limit(1).first() 
print 'query result:', [c for c in result.comments if c.user_id == 'user_c'] 
+0

谢谢! Благодарим за помощь! – user2089487

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