简体   繁体   English

在数组 PyMongo 中查找子文档

[英]Find a subdocument in array PyMongo

I want to query what comments have been made by any User about machine learning book between '2020-03-15' and '2020-04-25', ordered the comments from the most recent to the least recent.我想查询任何用户在“2020-03-15”和“2020-04-25”之间对机器学习书发表了哪些评论,将评论从最近到最近排序。

Here is my document.这是我的文件。

lib_books = db.lib_books
document_book1 = ({
    "bookid" : "99051fe9-6a9c-46c2-b949-38ef78858dd0",
    "title" : "Machine learning",
    "author" : "Tom Michael",
    "date_of_first_publication" : "2000-10-02",
    "number_of_pages" : 414,
    "publisher" : "New York : McGraw-Hill",
    "topics" : ["Machine learning", "Computer algorithms"],
    "checkout_list" : [
    {
        "time_checked_out" : "2020-03-20 09:11:22",
        "userid" : "ef1234",
        "comments" : [
        {
            "comment1" : "I just finished it and it is worth learning!",
            "time_commented" : "2020-04-01 10:35:13"
        },
        {
            "comment2" : "Some cases are a little bit outdated.",
            "time_commented" : "2020-03-25 13:19:13"
        },
        {
            "comment3" : "Can't wait to learning it!!!",
            "time_commented" : "2020-03-21 08:21:42"
        }]
    },
    {
        "time_checked_out" : "2020-03-04 16:18:02",
        "userid" : "ab1234",
        "comments" : [
        {
            "comment1" : "The book is a little bit difficult but worth reading.",
            "time_commented" : "2020-03-20 12:18:02"
        },
        {
            "comment2" : "It's hard and takes a lot of time to understand",
            "time_commented" : "2020-03-15 11:22:42"
        },
        {
            "comment3" : "I just start reading, the principle of model is well explained.",
            "time_commented" : "2020-03-05 09:11:42"
        }]
    }]
})

I tried this code, but it returns nothing.我试过这段代码,但它什么也没返回。

query_test = lib_books.find({"bookid": "99051fe9-6a9c-46c2-b949-38ef78858dd0", "checkout_list.comments.time_commented" : {"$gte" : "2020-03-20", "$lte" : "2020-04-20"}})
for x in query_test:
    print(x)

Can you try this你能试试这个

pipeline = [{'$match':{'bookid':"99051fe9-6a9c-46c2-b949-38ef78858dd0"}},//bookid filter
            {'$unwind':'$checkout_list'},
            {'$unwind':'$checkout_list.comments'},
            {'$match':{'checkout_list.comments.time_commented':{"$gte" : "2020-03-20", "$lte" : "2020-04-20"}}},
            {'$project':{'_id':0,'bookid':1,'title':1,'comment':'$checkout_list.comments'}},
            {'$sort':{'checkout_list.comments.time_commented':-1}}]

query_test = lib_books.aggregate(pipeline)
#{"bookid": "99051fe9-6a9c-46c2-b949-38ef78858dd0", "checkout_list.comments.time_commented" : {"$gte" : "2020-03-20", "$lte" : "2020-04-20"}})
for x in query_test:
    print(x)

I would recommend that you maintain comment field as one name, rather than keeping it as 'comment1', 'comment2', etc. If the field had been 'comment', it can be brought to the root itself我建议您将评论字段保留为一个名称,而不是将其保留为“comment1”、“comment2”等。如果该字段是“comment”,则可以将其带到根目录本身

Aggregate can be modified as below聚合可以修改如下

pipeline = [{'$match':{'bookid':"99051fe9-6a9c-46c2-b949-38ef78858dd0"}},//bookid filter
            {'$unwind':'$checkout_list'},
            {'$unwind':'$checkout_list.comments'},
            {'$match':{'checkout_list.comments.time_commented':{"$gte" : "2020-03-20", "$lte" : "2020-04-20"}}},
            {'$project':{'_id':0,'bookid':1,'title':1,'comment':'$checkout_list.comments.comment','time_commented':'$checkout_list.comments.time_commented'}},
            {'$sort':{'time_commented':-1}}]

MongoDB Query, in case if required MongoDB 查询,如果需要

db.books.aggregate([
{$match:{'bookid':"99051fe9-6a9c-46c2-b949-38ef78858dd0"}},//bookid filter
{$unwind:'$checkout_list'},
{$unwind:'$checkout_list.comments'},
{$match:{'checkout_list.comments.time_commented':{"$gte" : "2020-03-20", "$lte" : "2020-04-20"}}},
{$project:{_id:0,bookid:1,title:1,comment:'$checkout_list.comments.comment',time_commented:'$checkout_list.comments.time_commented'}},
{$sort:{'time_commented':-1}}
])

if there are multiple documents that you need to search, then you can use $in condition.如果需要搜索多个文档,则可以使用$in条件。

{$match:{'bookid':{$in:["99051fe9-6a9c-46c2-b949-38ef78858dd0","99051fe9-6a9c-46c2-b949-38ef78858dd1"]}}},//bookid filter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM