讨论背景
跟随elasticsearch和ik的安装和function score query 权重分查询教程,发现权重分查询结果与预期不符,判断原因是:在查询中,ik没有生效。
(es5以后权重分查询的api也有改变,如下:
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增加配置::
index.analysis.analyzer.default.tokenizer : "ik_max_word"
index.analysis.analyzer.default.type: "ik"
在es5以上的版本中,这个操作是会报错的。
修改索引太麻烦
你可能想修改索引,像stackoverflow的一个回答一样,让它带上默认analyzer:
// 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。
- 把旧的索引删除
DELETEhttp://localhost:9200/cityindex
- 在你需要添加analyzer的字段上添加
@Field(analyzer = "ik_max_word",type = FieldType.Text)
或@Field(analyzer = "ik_smart",type = FieldType.Text)
(es5以后"ik"字段被废弃)
@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=温岭
[
{
"id": 1,
"provinceid": 1,
"cityname": "温岭",
"description": "温岭是个好城市"
},
{
"id": 2,
"provinceid": 2,
"cityname": "温州",
"description": "温州是个热城市"
}
]
查询成功。
最后感谢关于spring-data-elasticsearch使用出现的一些小问题解决了最后的报错问题。