es的简单使用

使不使用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);
            }

        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值