【问题标题】:How to access MongoDB array in which is are stored key-value pairs by key name如何访问按键名存储键值对的 MongoDB 数组
【发布时间】:2020-08-19 19:00:12
【问题描述】:

我正在使用 pymongo 并在编写聚合查询之后

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

并接收提供的键的所有值。

【问题讨论】:

    标签: python json mongodb pymongo


    【解决方案1】:

    在来自 mongo shell 的以下查询中使用 $elemMatch projection 运算符:

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

    输出:

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


    使用PyMongo(得到相同的输出):

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

    使用PyMongo 聚合方法(得到相同的结果):

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

    【讨论】:

      【解决方案2】:

      将接收到的对象命名为“result”,如果 result['data'] 始终是具有 2 个键(keyvalue)的字典列表,则可以使用 keys 将整个列表转换为字典作为键和values 作为值。鉴于此语句有些混乱,代码如下:

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

      从这里,data['city'] 将给你'London'data['street'] 将是'Bigeye' 等等。显然,这是假设result['data'] 中的key 值之间没有冲突。请注意,这个字典(就像原来的 result['data'] 一样)只包含字符串,所以不要期望 data['number'] 是一个整数。

      另一种方法是动态创建一个对象,将每个键值对作为属性保存,允许您使用以下语法:data.city, data.street, ...但这需要更复杂的代码,并且一种不太常见且稳定的方法。

      【讨论】:

      • 对不起,我忘了说我想在 MongoDB 聚合查询的级别上做这件事。
      猜你喜欢
      • 2021-11-11
      • 2013-09-07
      • 1970-01-01
      • 1970-01-01
      • 2016-07-03
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2020-05-18
      相关资源
      最近更新 更多