在嵌套对象的某些元素上过滤 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"
}
]
}
]
}
比如我要获取的是所有的记录有:
- 匹配 'mog' 字段的子字符串 'value'
- 并同时为字段 'name'
匹配 'Numero de page'
例如字段 '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}],
[])
})
})
})
我很难理解如何根据以下数据的嵌套元素的子字符串匹配,使用 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"
}
]
}
]
}
比如我要获取的是所有的记录有:
- 匹配 'mog' 字段的子字符串 'value'
- 并同时为字段 'name' 匹配 'Numero de page'
例如字段 '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}],
[])
})
})
})