最近工作业务使用到了ElasticSearch(以下简称ES)搜索引擎,所以就简单的学了一下,对于遇到的小坑也记录一下(主要是字符串的排序和范围查询,在此也主要是记录这个),作为以后回顾。
1.Elasticsearch的mapping
ES的其他基本的概念就先不说了,主要说一下ES的mapping。
ES的mapping有点像静态语言中的数据类型,相当于设置存储的类型,这里主要讨论字符串类型。
ES 5.0以后,移除了string类型,string被拆分成两种新的数据类型: text用于全文搜索的,而keyword用于关键词搜索。
ES字符串将默认同时映射成text和keyword类型,自动创建动态映射(dynamic mappings):
{
"content": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
Text和keyword的主要区别(很重要)
Text:会先进行分词,然后进行索引,不支持聚合(例:“hello word”,索引时,会被分成“hello”和“word”2个词进行索引)
keyword:不进行分词,直接索引,支持聚合(例:“hello word”,按照“hello word”直接进行索引)
2.ES的字符串操作
了解了text和keyword的区别,我们就可以根据具体需求做相关操作了。
ES的字符串比较规则是第一位和第一位比较,一位一位的比较下去。
2.1字符串排序
按字符串排序时,很明显,我们是不希望分词之后进行排序的,而是应该以整个字符串整体来进行排序。
下面是kibana的Dev tool命令
GET /lib/_search
{
"query": {
"match_all": {}
}
, "sort": [
{
"content.keyword": {
"order": "desc"
}
}
]
}
注:此处字段均为字符串类型(mapping所展示的格式),对于需要排序的字段,必须使用keyword类型,才可以正确生效。
java客户端排序代码:
searchResponse = client.prepareSearch("index")
.setQuery(boolQuery)
.setSearchType(SearchType.QUERY_THEN_FETCH)
.addSort("content.keyword", SortOrder.DESC)
.get();
2.2字符串范围查询
同样是利用keyword的不分词的特性。
下面是kibana的Dev tool命令
GET /fptest_2019-04-03/rrr/_search
{
"query":{
"range": {
"birthday.keyword": {
"gte": "1994-01-01",
"lte": "1994-12-31",
"format": "yyyy-MM-dd"
}
}
}
}
注:range查询使用的参数
- gte:大于等于
- gt:大于
- lte:小于等于
- lt:小于
也可以使用from: to:,
java代码(构建查询条件)
QueryBuilders.rangeQuery("birthday.keyword").from(timeStart).to(timeEnd).format("yyyy-MM-dd")
最后说一句,如果是数字比较和数字范围查询,修改mapping才是王道。。。。