elastic search 解决地名地址别名搜索

1,335 阅读2分钟

准备

  • 安装 elastic search

  • 安装 kibana (这个不是必须的,但是为了操作方便,最好配置好)

  • 安装 jieba 插件

    这些步骤可以看我的上一篇文章,步骤很详细了:juejin.cn/post/684490…

定义 index

PUT pattern
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer":{
          "type":"custom",
          "char_filter":["mapping_filter"],
          "tokenizer":"jieba_search",    # 这里是用到了 jieba 分词工具,需要提前安装 jieba 插件
          "filter":["synonym_filter"]
          }
        },
        "char_filter": {
          "mapping_filter": {
            "type": "mapping",
            "mappings":["aaa => 666"] # 这里是做映射的,我没有用到,只是随便写了一个无用的键值对,可以删去该 char_filter 部分。
          }
        },
        "filter": {
          "synonym_filter": {
            "type": "synonym",  
            "expand":true,   # 设置为 true 如果有多个同义词,则都会找出
            "lenient": true,   # 设置为 true 在找同义词过程中遇到错误或者异常不会影响程序退出
            "synonyms_path":"synonyms.txt"  # 这个文件在 config 下存放即可,里面的内容就是用到的同义词 
          }
        }
      }
    },
    "mappings": {
      "properties": {
        "address":{
          "type": "text",
          "analyzer": "my_analyzer"
        }
      }
    }
  }

synonyms.txt

惠民苑9幢 => 中河中路71号
金隆花园金桂轩 => 佑圣观路128号
住宅楼 => 惠民苑1幢
广宇吴山鸣翠苑 => 四宜路3号
湖滨银泰C区 => 延安路258号   # 下面测试用该地址
湖滨银泰E区 => 延安路185号
湖滨银泰D区 => 延安路239号
湖滨银泰A区 => 东坡路7号
...

将标准的地址数据导入 elastic search 中

这一步主要是用程序将数据导入,我用的是 python ,具体数据自己找,我的数据是单位的,不适合分享。

查询

在 kibana 中输入以下命令

GET /pattern/_search
{
  "query": {
    "match": {
      "address": "湖滨银泰C区"
    }
  }
}

结果

{
  "took" : 92,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 10000,
      "relation" : "gte"
    },
    "max_score" : 10.722204,
    "hits" : [
      {
        "_index" : "pattern",
        "_type" : "_doc",
        "_id" : "K0JYs2wBv45n9wHi68Wa",
        "_score" : 10.722204,       
        "_source" : {
          "address" : "浙江省杭州市上城区湖滨街道延安路258号"   # 从地址可以看出基本和
    },
    	...
    	}
    ]
  }
}