使不使用keyword进行查询
1、ES5.0及以后的版本取消了string类型,将原先的string类型拆分为text和keyword两种类型,他们的区别就在于text会对字段进行分词处理而keyword则不会。
# 例如“中国123”会被分词为“中”、“国”和“123”
# 在text类型下,搜索“中国”是找不到的,此时需要使用 .keyword 的形式
2、当用户没有以IndexTemplate等形式为索引字段预先指定mapping的话,ES就会使用DynamicMapping,通过推断你传入的文档中字段的值对字段进行动态映射,
例如传入的文档中字段price值为12,那么price将被映射为long类型;字段addr的值为"192.168.0.1",那么addr字段将被映射为ip类型。然而对于不满足ip和date格式的普通字符串来说,情况有点不同:es会将他们映射为text类型,但为了保留对这些字段做精准查询以及聚合的能力,又同时对它们做了keyword类型的映射,作为该字段的fields属性写到_mapping中。例如
{
"foo":{
"type":"text",
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":256
}
}
}
}
后面的查询中,使用foo是将foo作为text类型来查询,而使用foo.keyword则是将foo作为keyword类型来查询,前者会对查询内容做分词处理再匹配,而后者则是直接查询结果做精确匹配。
例如es里面foo存“中国23”,将foo和“中”或者“国”可以匹配到,但是和“中国”是匹配不到的,【因为“中国”被分词了】,这时需要使用的是foo.keyword;但是foo可以匹配数字“23”,因为数字没有被分词,字母也会被分词
3、es的term query做的是精确匹配而不是分词查询,因此对text类型的字段做term查询将是查不到结果的(除非字段本身经过分词器处理后不变,未被转换或分词),因此必须使用foo.keyword来对foo字段以keyword类型进行精确匹配。
4、针对Numeric datatypes(long, integer, short, byte, double, float…),没有模糊查询wildcardQuery的用法
使用kibana常见命令
# ES里面没有索引的话,就创建索引
PUT /door
PUT /alarm
PUT /park
# 创建各个索引的别名
PUT /door/_alias/door_current
PUT /alarm/_alias/alarm_current
PUT /park/_alias/park_current
# 查询别名下面的所有内容
GET /alarm_all/_search
{
"query": {
"match_all": {
}
}
}
#查询别名为door_all的索引
GET /*/_alias/door_all
#查询索引door都有哪些索引别名
GET /door/_alias/*
# 复制索引内容
POST _reindex
{
"source": {
"index": "park"
},
"dest": {
"index": "park_current"
}
}
#### 下面的例子来熟悉一下ES的增删改查 ####
# 新建一个test索引
PUT /test
{
"mappings": {
"properties": {
"title":{"type": "text"},
"name":{"type": "text"},
"age":{"type": "integer"},
"created":{
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
}
}
},
"settings": {
"index":{
"number_of_shards":1,
"number_of_replicas":0
}
}
}
#### 查询 ####
# 查看test的settting
GET /test/_settings
# 查看test的mapping
GET /test/_mapping
# 查询test里面主键为1的内容
GET /test/_doc/1
# 查询test里面主键为1的age字段的内容
GET /test/_doc/1?_source=age
# 查询test里面的所有内容
GET /test/_search
{
"query": {
"match_all": {
}
}
}
# 根据name来查询,不会模糊查询
GET /test/_search
{
"query": {
"match": {
"name": "zs"
}
}
}
# 排序查询
GET /test/_doc
{
"query":{
"match": {
"name": "ww"
}
},
"sort":[
{
"date":{
"order":"desc"
}
}
]
}
# 附带分页的查询方式
GET /test/_search
{
"query": {
"match_all": {
}
},
"from": 0,
"size": 3
}
#### 增加 ####
# 往test里面写数据
PUT /test/_doc/5
{
"name":"zw",
"title":"张五",
"age":28,
"created":"2020-11-01"
}
#### 修改 ####
# 覆盖式更新
PUT /test/_doc/1
{
"name":"zs",
"title":"张三",
"age":18,
"created":"2020-01-01"
}
# 修改文档里面的某些字段
POST /test/_doc/1/_update
{
"doc":{
"age":20
}
}
#### 删除 ####
# 删除test里面的主键为FOHEW3ABPeUHy0w_4ugQ的数据
DELETE /test/_doc/FOHEW3ABPeUHy0w_4ugQ
es 常见用法
public void executeSearch() throws IOException {
logger.info("searching...");
String index = "es_my_index";
String name_text = "k";
String age_integer = "61183";
String name_keyword = "4";
Integer pageNum = 1;
Integer pageSize = 10;
BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
//模糊查询
BoolQueryBuilder shouldBuilder = QueryBuilders.boolQuery();
shouldBuilder.should(QueryBuilders.wildcardQuery("name_text", "*" + name_text + "*"));
boolBuilder.must(shouldBuilder);
boolBuilder.must(QueryBuilders.termsQuery("name_keyword", name_keyword));
boolBuilder.must(QueryBuilders.termsQuery("name_text", name_text));
boolBuilder.must(QueryBuilders.termQuery("age_integer", age_integer));
//分页查询
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(boolBuilder).from((pageNum - 1) * pageSize).size(pageSize);
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
getResult(searchResponse);
}
private void getResult(SearchResponse searchResponse) {
SearchHit[] searchHits = searchResponse.getHits().getHits();
long totalHits = searchResponse.getHits().getTotalHits().value;
logger.info("共查出{}条记录", totalHits);
if (searchResponse.status().getStatus() == 200) {
List<Map<String, Object>> sourceList = new ArrayList<>();
for (SearchHit searchHit : searchHits) {
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
sourceList.add(sourceAsMap);
JSONObject source = JSONObject.parseObject(searchHit.getSourceAsString());
String name_keyword = source.getString("name_keyword");
String name_text = source.getString("name_text");
String age_integer = source.getString("age_integer");
String man_boolean = source.getString("man_boolean");
logger.info("共查出{}条记录 >> name_keyword:{}//name_text:{}//age_integer:{}//man_boolean:{}",
totalHits, name_keyword, name_text, age_integer, man_boolean);
}
}
}