在嵌套对象

时间:2016-01-07 00:43:27

标签: python json nested rethinkdb

我很难理解如何根据以下数据的嵌套元素上的子字符串匹配过滤我的rethinkdb表:

{
// HERE WE HAVE MANY RECORDS
    "record":  "0a76d012-f83d-4bd3-95b7-2ba973750bde" ,
    "steps": 
    [ 
// HERE WE HAVE MANY STEPS
        {
            "step": 1,
            "latest_db_info": { ... } ,
            "data": 
            [
               {
                    "hash":  "2ba7e669" ,
                    "name":  "Numero de l'extrait" ,
                    "position": 1 ,
                    "value":  "Limoges_34"
                } ,
                {
                    "hash":  "d094874e" ,
                    "name":  "Numero de page de l'extrait" ,
                    "position": 2 ,
                    "value":  "Limoges_p. 34"
                } ,
                {
                    "hash":  "598653a6" ,
                    "name":  "Type de l'extrait" ,
                    "position": 3 ,
                    "value":  "texte"
                }
            ]
        }
    ]
}

我想要的是,例如,获取所有记录:

  • 子串匹配' mog'对于字段'值'
  • 同时匹配' Numero de page'对于该字段' name'

例如,字段的路径'值'是这样的:

{'steps': [{'data': [['value' ...

我尝试使用lambda function进行直接过滤,但没有给出任何结果。 我使用concat_map

获得了一些结果
r.table('mytable') \
    .concat_map(r.row['steps']) \
    .concat_map(r.row['data']) \
    .filter(
        lambda row: row['value'].match('mog')
    ).run()

但结果松了原来的record字段......

[{'position': 1, 'hash': '2ba7e669', 'value': 'Limoges_34', 'name': "Numero de l'extrait"}, 
[...]

有人能引导我朝正确的方向前进吗? 另外一个javascript示例会有所帮助。

编辑:感谢@kureikain接受的答案。这是未来参考的python版本:

r.table('mytable') \
    .concat_map(
        lambda doc: doc['steps'] \
            .concat_map(lambda step: step['data'] \
                .concat_map(lambda data: [{'record': doc['record'], 'step': data}]
    ))) \
  .filter(
    lambda doc: 
        doc['step']['value'].match('mog').and_(doc['step']['name'].match('Numero de page'))
  ).run()

1 个答案:

答案 0 :(得分:1)

使用嵌套语法进行过滤仅适用于嵌套对象,我们无法使用嵌套语法选择/查询数组。

如果您想要包含与您的值匹配的record字段和step/data记录,可以使用这样的代码:

r.table('mytable')
  .concatMap(function(doc) {
    return doc('steps')
      .concatMap(function(step) {
        return step('data').concatMap(function(data) {
          return [{record: doc('record'), step: data}]
        })
      })
  })

  .filter(function(doc) {
    return doc('step')('value').eq('mog').and(doc('step')('name').eq('Numero de page'))
  })

或者换句话说,不使用filter

r.table('mytable')
  .concatMap(function(doc) {
    return doc('steps')
      .concatMap(function(step) {
        return step('data').concatMap(function(data) {
          return
            r.branch(data('value').eq('Limoges_34').and(data('name').eq('Numero de l\'extrait')),
              [{record: doc('record'), step: data}],
              [])
        })
      })
  })