我试图在elasticsearch中存储地理区域的分层数据,以便进行模糊匹配。
实施例
USA-> California-> Santa Clara County-> Palo Alto-> Palo Alto St。
目前我将所有内容存储在一个扁平结构中,其名称和路径如下所示:
{
"name" : "Palo Alto St.",
"path" : [
"USA",
"California",
"Santa Clara County",
"Palo Alto"
]
}
“Palo Alto”看起来很相似
{
"name" : "Palo Alto",
"path" : [
"USA",
"California",
"Santa Clara County"
]
}
然后我运行了一个这样的fuzzy_like_this查询:
{
"query": {
"fuzzy_like_this": {
"like_text": "palo alto",
"fields": [
"name",
"path"
],
"min_similarity": 0.9,
"prefix_length": 2
}
}
}
不幸的是,当我想要提高树中最深处的结果得分时,这似乎不太好用。
是否有一些标准方法可以做到这一点,例如父/子关系?我做了一些挖掘,但没有提到任意长度的分层数据。
我做了一些自定义分数查询,但它似乎不够灵活,或者我的理解有点过于肤浅。
感谢您阅读
答案 0 :(得分:1)
我会给这个人一个刺!我建议你使用嵌套文档和custom_filters_score查询(替换为.90.4中的函数分数。我还没有完全调查那个。
首先,我们只需将“名称”字段放在层次结构路径中即可。您可以随时提升名称字段匹配1.5或2x并保持字段不变,但这将使我们更清晰。我还要求您将数据格式更改为这样。
{
"name": "Palo Alto",
"path": [
{
"name": "USA",
"level": 1
},
{
"name": "California",
"level": 2
},
{
"name": "Santa Clara County",
"level": 3
},
{
"name": "Palto Alto",
"level": 4
}
]
}
现在,我将把你改为你的字段映射的嵌套文档。
{
"my_document": {
"properties": {
"path": {
"type": "nested",
"properties": {
"name": {
"type": "string"
},
"level": {
"type": "integer"
}
}
}
}
}
}
现在我们要做一个查询,这看起来有点疯狂。而且,说实话,有一些替代方案可以让你在那里进行一些定制。此外,我可以忽略一些明显的东西,但我很乐意听到它。嘿,已经很晚了!
{
"query": {
"custom_filters_score": {
"query": {
"constant_score": {
"query": {
"nested": {
"path": "path",
"query": {
"fuzzy_like_this_field": {
"path.name": {
"like_text": "palo alto",
"min_similarity": 0.9,
"prefix_length": 2
}
}
}
}
},
"boost": 1
}
},
"filters": [
{
"filter": {
"nested": {
"path": "path",
"query": {
"bool": {
"must": [
{
"fuzzy_like_this_field": {
"name": {
"like_text": "palo alto",
"min_similarity": 0.9,
"prefix_length": 2
}
}
},
{
"term": {
"level": 2
}
}
]
}
}
}
},
"boost": 1
},
{
"filter": {
"nested": {
"path": "path",
"query": {
"bool": {
"must": [
{
"fuzzy_like_this_field": {
"name": {
"like_text": "palo alto",
"min_similarity": 0.9,
"prefix_length": 2
}
}
},
{
"term": {
"level": 3
}
}
]
}
}
}
},
"boost": 2
},
{
"filter": {
"nested": {
"path": "path",
"query": {
"bool": {
"must": [
{
"fuzzy_like_this_field": {
"name": {
"like_text": "palo alto",
"min_similarity": 0.9,
"prefix_length": 2
}
}
},
{
"term": {
"level": 4
}
}
]
}
}
}
},
"boost": 3
},
{
"filter": {
"nested": {
"path": "path",
"query": {
"bool": {
"must": [
{
"fuzzy_like_this_field": {
"name": {
"like_text": "palo alto",
"min_similarity": 0.9,
"prefix_length": 2
}
}
},
{
"term": {
"level": 5
}
}
]
}
}
}
},
"boost": 4
},
{
"filter": {
"nested": {
"path": "path",
"query": {
"bool": {
"must": [
{
"fuzzy_like_this_field": {
"name": {
"like_text": "palo alto",
"min_similarity": 0.9,
"prefix_length": 2
}
}
},
{
"term": {
"level": 6
}
}
]
}
}
}
},
"boost": 5
}
],
"score_mode" : "max"
}
}
}