springboot整合elasticsearch 5.x 6.x 索引配置analyzer

2019-05-25 08:55:10 浏览数 (1)

讨论背景

跟随elasticsearch和ik的安装和function score query 权重分查询教程,发现权重分查询结果与预期不符,判断原因是:在查询中,ik没有生效。 (es5以后权重分查询的api也有改变,如下:

代码语言:javascript复制
FunctionScoreQueryBuilder.FilterFunctionBuilder[] functionScoreQueryBuilder = {
    new FunctionScoreQueryBuilder.FilterFunctionBuilder(
        QueryBuilders.matchQuery("cityname", searchContent),
        ScoreFunctionBuilders.weightFactorFunction(1)),
    new FunctionScoreQueryBuilder.FilterFunctionBuilder(
        QueryBuilders.matchQuery("description", searchContent),
        ScoreFunctionBuilders.weightFactorFunction(100))
};

FunctionScoreQueryBuilder query = QueryBuilders.functionScoreQuery(functionScoreQueryBuilder);

 // 创建搜索 DSL 查询
SearchQuery searchQuery = new NativeSearchQueryBuilder()
    .withPageable(pageable)
    .withQuery(query).build();

)

旧的教程无效

有时你想为索引添加analyzer,但网上的教程都是叫你在 elasticsearch-2.3.2/config/elasticsearch.yml增加配置::

代码语言:javascript复制
index.analysis.analyzer.default.tokenizer : "ik_max_word"
index.analysis.analyzer.default.type: "ik"

在es5以上的版本中,这个操作是会报错的。

修改索引太麻烦

你可能想修改索引,像stackoverflow的一个回答一样,让它带上默认analyzer:

代码语言:javascript复制
// close index
curl -XPOST 'localhost:9200/test1/_close'

                            add this to the path
                                     |
                                     v
curl -XPUT localhost:9200/test1/_settings?pretty -d '{                                                                           "index":{
"analysis" : {
            "analyzer" : {
                "default" : {
                    "type" : "ik"
                }
            }
        }
    }
}'

// re-open index
curl -XPOST 'localhost:9200/test1/_open'

这个操作似乎没有效果。 又在想是否要修改mapping,给每个属性配置analyzer,但看到github issue有老外说很少有人会中途改索引的mapping的

I'm pretty sure I remember changing the search analyzer on the fly a few times.

解决方法

你要让springboot运行时创建的索引就自带analyzer。

  1. 把旧的索引删除 DELETE http://localhost:9200/cityindex
  2. 在你需要添加analyzer的字段上添加@Field(analyzer = "ik_max_word",type = FieldType.Text)@Field(analyzer = "ik_smart",type = FieldType.Text)(es5以后"ik"字段被废弃)
代码语言:javascript复制
@Document(indexName = "cityindex", type = "city")
public class City implements Serializable{
    private static final long serialVersionUID = -1L;

    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String cityname;

    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String description;
    ...
}

记得type字段要加,否则报错,详见关于spring-data-elasticsearch使用出现的一些小问题

@Field中也可以指定search_analyzer字段。这样程序运行时新建的索引就自带分析器了。

检验效果

GET http://localhost:8080/api/city/search?pageNumber=0&pageSize=10&searchContent=温岭

代码语言:javascript复制
[
    {
        "id": 1,
        "provinceid": 1,
        "cityname": "温岭",
        "description": "温岭是个好城市"
    },
    {
        "id": 2,
        "provinceid": 2,
        "cityname": "温州",
        "description": "温州是个热城市"
    }
]

查询成功。

最后感谢关于spring-data-elasticsearch使用出现的一些小问题解决了最后的报错问题。

0 人点赞