在es中,如果字段名中包含双下划线,es是被允许的,但是我最近在使用py的es dsl库的时候,发现一个问题,就是字段名称如果带有双下划线。例如 a__b__c 就查询不出东西,经过debug发现在es的dsl内部经过转换后,最终生成的es的查询语法中,a__b__c已经变成了a.b.c,这意味着字段名称和es的已经不匹配了,自然就查询不出东西。

经过分析,以及相关的搜索:

https://stackoverflow.com/questions/51050043/multiple-underscores-in-elasticsearch-field-name-with-python-elasticsearch-dsl

可以得知,es的py dsl在设计的时候,借鉴的是Django ORM 设计思路,而在Django ORM 的设计中,__ 也就是双下划线, 代表着嵌套查询,因为是嵌套查询了,那么a__b__c 自然也就会被翻译成 a.b.c 了。

https://github.com/elastic/elasticsearch-dsl-py/issues/28

在这个issue中,社区进行了大量讨论,不过都对要做转换这个结论是认可的。

具体到代码的位置:

https://github.com/elastic/elasticsearch-dsl-py/blob/605d7570e2a1501f319fdc74ad8d8270a5e61ea2/elasticsearch_dsl/utils.py#L222-L223

def __init__(self, _expand__to_dot=EXPAND__TO_DOT, **params):
self._params = {}
for pname, pvalue in iteritems(params):
if '__' in pname and _expand__to_dot:
pname = pname.replace('__', '.')
self._setattr(pname, pvalue)

可以看到这里做了转换。

不过作为es的dsl库,约束不像es向下对齐,而是向上对齐,也是少见了。


扫码手机观看或分享: