Цепочка сбора MongoDB

#python #mongodb #pymongo

#python #mongodb #pymongo

Вопрос:

У меня есть проблема, которую мне нужно решить. В настоящее время мой код работает с одной коллекцией, где я создаю курсор для одной коллекции сборок. Это выглядит так:

 from pymongo import MongoClient
from itertools import chain

db = MongoClient('10.39.165.193', 27017)['mean-dev']
cursor = db.collection1.find().limit(10).sort('number', -1)
  

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

 cursor2 =  db.collection1.find().limit(10).sort('number', -1)
joinCursors = ... # Somehow join cursors
  

Я пробовал это (но это не сработало):

 joinCursor = [x for x in chain(cursor1, cursor2)]
  

Когда я просто печатаю joinCursor. Я получаю последнее, что есть в моей БД, а это не то, что я хочу. То, что я хочу, это то же самое, что и когда я возвращаю только cursor1, который является: . Чтобы я мог использовать для таких вещей, как подсчет, пример:

 counter = joinedCursor.count(True)
  

Ответ №1:

Один из способов решить эту проблему — написать свой собственный JoinedCursor класс, подобный этому:

 class JoinedCursor:
    def __init__(self, db, collection1, collection2, limit=None, sort_on=None, order=1):
        self.limit = limit
        self.sort_on = sort_on
        self.order = order
        self.cursor1 = db[collection1].find()
        self.cursor2 = db[collection2].find()

    def __iter__(self):

        for doc in self.cursor1.limit(self.limit).sort(self.sort_on, self.order):
            yield doc
        for doc in self.cursor2.limit(self.limit).sort(self.sort_on, self.order):
            yield doc

    def count(self):

        return self.cursor1.count()   self.cursor2.count()
  

Затем это позволяет вам создать объединенный курсор для двух коллекций следующим образом:

 db = pymongo.MongoClient()["test-join"]
joined_cursor = JoinedCursor(db, "collection1", "collection2", limit=10, sort_on="num", order=-1)
  

Вы можете последовательно перебирать оба цикла с помощью цикла for и вызывать count метод:

 for doc in joined_cursor:
    print(doc)

print(joined_cursor.count())
  

Конечно, это можно было бы сделать более обобщенным, чтобы взять две или более коллекций и применять запросы и т.д.

Комментарии:

1. Мне было интересно, знаете ли вы, почему я получаю эту ошибку при использовании курсора, присоединенного к вашему классу. Недопустимая операция: невозможно установить параметры после выполнения запроса. это происходит, когда: для di в di_cursor: di_list.append(di[‘id’]) di_cursor.rewind()