Как получить доступ к массиву MongoDB, в котором хранятся пары ключ-значение по имени ключа - PullRequest
0 голосов
/ 05 мая 2020

Я работаю с pymon go и после написания совокупного запроса

db.collection.aggregate([{'$project': {'Id': '$ResultData.Id','data' : '$Results.Data'}}])

я получил объект:

{'data': [{'key': 'valid', 'value': 'true'},
      {'key': 'number', 'value': '543543'},
      {'key': 'name', 'value': 'Saturdays cx'},
      {'key': 'message', 'value': 'it is valid.'},
      {'key': 'city', 'value': 'London'},
      {'key': 'street', 'value': 'Bigeye'},
      {'key': 'pc', 'value': '3566'}],

Есть ли способ Я могу получить доступ к значениям по имени ключа? Вот так '$Results.Data.city', и я получу Лондон. Я хотел бы сделать это на уровне агрегированного запроса MongoDB, поэтому это означает, что я хочу написать запрос следующим образом:

db.collection.aggregate([{'$project': 
    {'Id': '$ResultData.Id',
    'data' : '$Results.Data',
    'city' : $Results.Data.city',
    'name' : $Results.Data.name',
    'street' : $Results.Data.street',
    'pc' : $Results.Data.pc',
            }}])

И получить все значения предоставленных ключей.

Ответы [ 2 ]

3 голосов
/ 05 мая 2020

Использование оператора $ elemMatch projection в следующем запросе из mon go shell :

db.collection.find(
  { _id: <some_value> }, 
  { _id: 0, data: { $elemMatch: { key: "city" } } } 
)

Результат:

{ "data" : [ { "key" : "city", "value" : "London" } ] }


Использование PyMon go (получает тот же результат):

collection.find_one( 
  { '_id': <some_value> }, 
  { '_id': 0, 'data': { '$elemMatch': { 'key': 'city' } } } 
)

Использование PyMon go совокупный метод (дает тот же результат):

pipeline = [
  {
      '$project': {
         '_id': 0,
          'data': {
              '$filter': {
                  'input': '$data', 'as': 'dat',
                  'cond': { '$eq': [ '$$dat.key', INPUT_KEY ] }
              }
          }
      }
  }
]

INPUT_KEY = 'city'

pprint.pprint(list(collection.aggregate(pipeline)))
0 голосов
/ 05 мая 2020

Называя полученный объект «result», если result['data'] всегда является списком словарей с двумя ключами (key и value), вы можете преобразовать весь список в словарь, используя key s как ключи и value s как значения. Учитывая, что это утверждение несколько сбивает с толку, вот код:

data = {pair['key']: pair['value'] for pair in result['data']}

Отсюда data['city'] даст вам 'London', data['street'] будет 'Bigeye' и так далее. Очевидно, это предполагает отсутствие конфликтов среди key значений в result['data']. Обратите внимание, что этот словарь (как и исходный result['data']) будет содержать только строки, поэтому не ожидайте, что data['number'] будет целым числом.

Другой подход заключается в динамическом создании объекта, содержащего каждое значение ключа. пара в качестве атрибута, что позволяет использовать следующий синтаксис: data.city, data.street, ... Но это потребует более сложного кода и является менее распространенным и стабильным подходом.

...