Как правильно комбинировать $ in и $ elemMatch с MongoDB (PyMongo) - PullRequest
1 голос
/ 26 октября 2019

В моей базе данных хранятся данные по следующей схеме:

{'_id': ...,
 'names': [{'first': ...,
            'last': ...},
           {'first': ...,
            'last': ...},
           ...
           ],
...
}

Теперь в моей программе я получаю список имен по следующей схеме:

name_list = [(first_name1, last_name1), (first_name2, last_name2), ...]

Я хочу найти все документы, в которых любая из этих комбинаций имени / фамилии в name_list содержится в массиве names.

Если бы у меня было простоодно имя для проверки (вместо списка), я бы использовал следующий запрос:

query = {'names':
                 {'$elemMatch':
                      {'first_name': first_name,
                       'last_name': last_name}
                  }}

Так что я мог бы предоставить этот запрос для каждого имени в списке, выполнив что-то вроде:

all_results = []
for first_name, last_name in name_list:
    rv := # Result from query
    # combine all_results and rv

Но я чувствую, что должен быть лучший способ сделать это.

1 Ответ

1 голос
/ 26 октября 2019

Многоэлементный запрос на совпадение может быть создан из name_list с использованием $or и $elemMatch, который работаеттаким образом, чтобы найти документы, в которых совпадает любая из этих первой / последней комбинации.

Запрос: , считая name_list равным

//[(first_name1, last_name1), (first_name2, last_name2), (first_name3, last_name3)]

db.collection.find({
  $or: [
    {
      names: {
        $elemMatch: {
          first: "first_name1",
          last: "last_name1"
        }
      }
    },
    {
      names: {
        $elemMatch: {
          first: "first_name2",
          last: "last_name2"
        }
      }
    },
    {
      names: {
        $elemMatch: {
          first: "first_name3",
          last: "last_name3"
        }
      }
    }
  ]
});
...