Elasticsearch查询常见问题
1、实现mysql中的like查询效果
使用 NGram 分词器作为字段的分词器,可在索引创建时指定,也可以更新映射关系,以下展示如何在索引创建时指定 NGram 分词器。
{
"settings": {
"analysis": {
"analyzer": {
"ngram_analyzer": {
"tokenizer": "ngram_tokenizer"
}
},
"tokenizer": {
"ngram_tokenizer": {
"type": "ngram",
"min_gram": 1,
"max_gram": 30,
"token_chars": [
"letter",
"digit"
]
}
}
}
},
"mappings": {
"_default_": {
"properties": {
"Name": {
"type": "string",
"analyzer": "ngram_analyzer"
}
}
}
}
}
2、当需要在一个字段上同时进行模糊查询、排序时
可以指定2个分词器
"mappings": {
"_default_": {
"properties": {
"Name": {
"type": "string",
"analyzer": "ngram_analyzer",
"fields": {
"raw": {
"type": "keyword" }
}
}
}
}
}
对Name.raw进行排序
3、解决 Elasticsearch 超过 10000 条无法查询的问题
方法一:重建索引,修改最大显示数据大小
具体操作命令,如下(比如,设置可查询 200000000 条数据,其中 alarm 是index名称):
PUT alarm/_settings
{
"max_result_window" : 200000000
}
方法二:使用es自带的scroll分页支持
初始化查询
//构建查询条件(非必须)
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("rate_object","item"));
RangeQueryBuilder publishDateBuilder = QueryBuilders.rangeQuery("created_at");
publishDateBuilder.from("2018-04-22 00:00:00");//格式需要同你创建索引时的格式匹配
boolQueryBuilder.filter(publishDateBuilder);
TransportClient client = factory.getClient();
SearchResponse response = client.prepareSearch("index")//对应索引
.setTypes("type")//对应索引type
.setQuery(boolQueryBuilder)
.setScroll(TimeValue.timeValueMinutes(10))//设置查询context的存活时间
.setSize(100)
.execute()
.actionGet();
迭代查询
while (response.getHits().getHits().length>0) {
String scrollId = response.getScrollId();
response = client.prepareSearchScroll(scrollId)
.setScroll(TimeValue.timeValueMinutes(10))//设置查询context的存活时间
.execute()
.actionGet();
SearchHits hits = response.getHits();
for (SearchHit hit:hits.getHits()) {
String hitString = hit.getSourceAsString();
System.out.println(hitString);//此处可进行业务逻辑
}
}
clean scroll
ClearScrollRequest request = new ClearScrollRequest();
request.addScrollId(response.getScrollId());
client.clearScroll(request);