在嵌套对象的某些元素上过滤 Rethinkdb table

Filtering a Rethinkdb table on some element of a nested object

我很难理解如何根据以下数据的嵌套元素的子字符串匹配,使用 Python 过滤我的 rethinkdb table:

{
// 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"
                }
            ]
        }
    ]
}

比如我要获取的是所有的记录有:

例如字段 'value' 的路径类似于:

{'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()

使用嵌套语法过滤仅适用于嵌套对象,我们无法select/query具有嵌套语法的数组。

如果你想包含 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}],
              [])
        })
      })
  })