Elasticsearch查询以在分析的字符串

时间:2016-09-08 22:25:21

标签: elasticsearch

如何创建有效查询以查找字符串中的街道地址?例如,用户的生物可以说“我们位于123 Main St”,字符串“123 Main St”应该匹配。我需要的模式是:一个或多个数字(例如[0-9] +),然后是1-4个单词(但不是0,如下所述)可以是任何东西(街道名称,例如“Main”)或“南五”或“马丁路德金小”),并以“街”或“大道”这样的词结尾。

这是我创建的初步查询,但是运行速度很慢:

{
  "_source": false,
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "span_near": {
            "clauses": [
              {
                "span_multi": {
                  "match": {
                    "regexp": {
                      "details.bio": "[0-9]+"
                    }
                  }
                }
              },
              {
                "span_multi": {
                  "match": {
                    "regexp": {
                      "details.bio": "[a-zA-Z0-9]+"
                    }
                  }
                }
              },
              {
                "span_multi": {
                  "match": {
                    "regexp": {
                      "details.bio": "St|st|street|Street|ave|Ave|AVE|Avenue|avenue|blvd|BLVD|Blvd|boulevard|Boulevard|drive|Drive|dr|DR|Dr|lane|Lane|Ln|ln|Road|road|Rd|rd"
                    }
                  }
                }
              }
            ],
            "slop": 0,
            "in_order": true
          }
        }
      ]
    }
  }
}

此查询中非常昂贵的部分是第二个正则表达式“[a-zA-Z0-9] +”。我尝试的第一个替代方案是删除它并添加4的“slop”,但是当slop为0时,这有太多的误报(例如,它匹配生物与“我21岁。街头智能......”)。所以我需要在不使用通配符的情况下在第一个表达式(街道号码)和第二个表达式(St,Blvd等)之间需要1-4个字,但不是0。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

解决了!我利用了" span_not"搜索。包括slop = 4的所有内容,然后排除slop = 0。运行大约2s vs 1m +。

{
    "span_not": {
        "include": {
            "span_near": {
                "clauses": [
                    {
                        "span_multi": {
                            "match": {
                                "regexp": {
                                    "details.bio": "[0-9]+"
                                }
                            }
                        }
                    },
                    {
                        "span_multi": {
                            "match": {
                                "regexp": {
                                    "details.bio": "St|st|street|Street|ave|Ave|AVE|Avenue|avenue|blvd|BLVD|Blvd|boulevard|Boulevard|drive|Drive|dr|DR|Dr|lane|Lane|Ln|ln|Road|road|Rd|rd"
                                }
                            }
                        }
                    }
                ],
                "slop": 4,
                "in_order": true
            }
        },
        "exclude": {
            "span_near": {
                "clauses": [
                    {
                        "span_multi": {
                            "match": {
                                "regexp": {
                                    "details.bio": "[0-9]+"
                                }
                            }
                        }

                },
                {
                    "span_multi": {
                        "match": {
                            "regexp": {
                                "details.bio": "St|st|street|Street|ave|Ave|AVE|Avenue|avenue|blvd|BLVD|Blvd|boulevard|Boulevard|drive|Drive|dr|DR|Dr|lane|Lane|Ln|ln|Road|road|Rd|rd"
                            }
                        }
                    }
                }
            ],
            "slop": 0,
            "in_order": true
        }
    }
}

}