Найти поддокумент в массиве PyMongo - PullRequest
1 голос
/ 25 апреля 2020

Я хочу спросить, какие комментарии был сделан любым Пользователем о книге по машинному обучению в период с '2020-03-15' до '2020-04-25', заказав комментарии от самого последнего к наименее последнему.

Вот мой документ.

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"
        }]
    }]
})

Я попробовал этот код, но он ничего не возвращает.

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)

1 Ответ

0 голосов
/ 26 апреля 2020

Можете ли вы попробовать это

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)

Я бы порекомендовал сохранить поле комментария как одно имя, а не как "comment1", "comment2" и т. Д. c. Если поле было «комментарием», оно может быть перенесено в сам root

Агрегат может быть изменен, как показано ниже

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, в случае необходимости

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}}
])

, если вам нужно выполнить поиск по нескольким документам, вы можете использовать условие $in.

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