MongoAlchemy query embedded documents

我的梦境 提交于 2019-12-22 01:32:05

问题


I want to know how to use MongoAlchemy about embeded docment operation. But I havn't find any documents about these. Can anyone give me some helps?

Here is demo code:

#!/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. I want to query data which user_id is "user_c", and just return back one Comment, How can I do that? Does these methods below are MongoAlchemy remommended? BTW, these methods will return the whole document.

    #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. How can I change "user_c" to "user_c_new" which find by query ?

  3. How can I remove one comment which user_id is "user_b"?

回答1:


Mongo doesn't support returning subdocuments. You can use $elemMatch to filter so that only documents with matching attributes are returned, but you'll have to grab the comments yourself. You could slightly optimize by only returning the comments field as follows:

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

Note that there was a bug with this up until 0.14.3 (which I just released a few minutes ago) which would have caused results.comments not to work.

Another very important note is that the elem_match I'm doing there only returns the first matching element. If you want all matching elements you have to filter them yourself:

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']


来源:https://stackoverflow.com/questions/20265271/mongoalchemy-query-embedded-documents

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!