赞
踩
全文检索:全部都检索,可以按照用户定义的查询规则任意查询,得到目标数据。
内部实现的原理就是倒排索引。
概念:
原理:
数据是如何分布:分片机制
数据是如何交互:平行节点 内部交互 节点对等的分布式架构
数据备份:副本机制
常见的数据类型:
- //建立连接
- RestHighLevelClient client = new RestHighLevelClient(
- RestClient.builder(
- new HttpHost("localhost", 9200, "http"),
- new HttpHost("localhost", 9201, "http")));
-
- //关闭客户端
- client.close();
-
- CreateIndexRequest request = new CreateIndexRequest("user");
- request.settings(Settings.builder()
- .put("index.number_of_shards", 3)
- .put("index.number_of_replicas", 1)
- );
- request.mapping(
- "{\n" +
- " \"properties\": {\n" +
- " \"id\": {\n" +
- " \"type\": \"long\"\n" +
- " },\n" +
- " \"name\":{\n" +
- " \"type\": \"keyword\"\n" +
- " },\n" +
- " \"age\":{\n" +
- " \"type\": \"integer\"\n" +
- " },\n" +
- " \"gender\":{\n" +
- " \"type\": \"keyword\"\n" +
- " },\n" +
- " \"note\":{\n" +
- " \"type\": \"text\",\n" +
- " \"analyzer\": \"ik_max_word\"\n" +
- " }\n" +
- " }\n" +
- " }",
- //指定映射的内容的类型为json
- XContentType.JSON);
- CreateIndexResponse response = client.indices()
- .create(request, RequestOptions.DEFAULT);
- User user = new User(110L, "张三", 22, "0", "翻斗小院");
- IndexRequest indexRequest = new IndexRequest("user");
- indexRequest.id(user.getId().toString());
- String userJson = JSON.toJSONString(user);
- indexRequest.source(userJson, XContentType.JSON);
- IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
注意:ES要是遇到id一致的话,实质是先删除后添加
- GetRequest getRequest = new GetRequest("user", "110");
- GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
- String sourceAsString = response.getSourceAsString();
- User user = JSON.parseObject(sourceAsString, User.class);
- System.out.println(user);
- DeleteRequest request = new DeleteRequest("user","110");
- DeleteResponse deleteResponse = client.delete(request,RequestOptions.DEFAULT);
- BulkRequest bulkRequest = new BulkRequest();
- for (User user : userList) {
- bulkRequest.add(new IndexRequest("user")
- .id(user.getId().toString())
- .source(JSON.toJSONString(user), XContentType.JSON)
- );
- }
- BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
大致流程
- sourceBuilder.query(
- QueryBuilders.matchAllQuery()
- );
- SearchRequest request = new SearchRequest("user");
- request.source(sourceBuilder);
- SearchResponse response = client.search(request, RequestOptions.DEFAULT);
- SearchHits searchHits = response.getHits();
- // 5.1.获取总条数
- long total = searchHits.getTotalHits().value;
- System.out.println("total = " + total);
- // 5.2.获取SearchHit数组,并遍历
- SearchHit[] hits = searchHits.getHits();
- for (SearchHit hit : hits) {
- //获取分数
- System.out.println("文档得分:"+hit.getScore());
- // - 获取其中的`_source`,是JSON数据
- String json = hit.getSourceAsString();
- // - 把`_source`反序列化为User对象
- User user = JSON.parseObject(json, User.class);
- System.out.println("user = " + user);
- }
-
- sourceBuilder.query(QueryBuilders.matchAllQuery());
-
ElasticSearch两个数据类型
sourceBuilder.query(QueryBuilders.termQuery("name", "小红"));
MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "小红");
设置修正的次数,最大为2
- FuzzyQueryBuilder queryBuilder = QueryBuilders.fuzzyQuery("note", "模糊查询");
- queryBuilder.fuzziness(Fuzziness.TWO);
- RangeQueryBuilder queryBuilder = QueryBuilders.rangeQuery("age");
- // 22 <= age < 27
- queryBuilder.gte(22);
- queryBuilder.lt(27);
- QueryStringQueryBuilder queryBuilder =
- QueryBuilders.queryStringQuery("同学")
- .field("name")
- .field("note")
- // .defaultField("note") // 默认搜索域
- .defaultOperator(Operator.AND);
- printResultByQuery(queryBuilder);
连接方式:
- // 1.构建bool条件对象
- BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
- // 2.构建matchQuery对象,查询相信信息`note`为: 同学
- MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("note", "同学");
- queryBuilder.must(matchQueryBuilder);
-
- // 3.过滤姓名`name`包含:小武
- TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "小武");
- queryBuilder.filter(termQueryBuilder);
-
- // 4.过滤年龄`age`在:23-27
- RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").gte(23).lte(27);
- queryBuilder.filter(rangeQueryBuilder);
-
- int page = 2; // 当前页
- int size = 2; // 一页显示条数
- int from = (page - 1) * size; // 每一页起始条数
- sourceBuilder.from(from);
- sourceBuilder.size(size);
高亮三要素:
- HighlightBuilder highlight = SearchSourceBuilder.highlight();
- highlight.field("note"); // 高亮显示域
- highlight.preTags("<font color='red'>"); // 高亮显示前缀
- highlight.postTags("</font>"); // 高亮显示后缀
- sourceBuilder.highlighter(highlight);
- //要把结果解析
- HighlightField highlightField = searchHit.getHighlightFields().get("note"); // get("高亮显示域名称")
- Text[] fragments = highlightField.getFragments();
- String note = StringUtils.join(fragments);
- // 判断如果是可以获取到数据则更新到用户对象中
- if (StringUtils.isNotBlank(note)) {
- user.setNote(note);
- }
参与聚合的字段,必须是keyword类型。
桶-数据分组
度量-聚合运算
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
- sourceBuilder.aggregation(
- AggregationBuilders
- .terms("popular_color")
- .field("color.keyword"));
- TermsAggregationBuilder popularColorAggs = AggregationBuilders.terms("popular_color").field("color.keyword");
-
- // ***分组后平均价格计算
- AvgAggregationBuilder priceAggs = AggregationBuilders.avg("avg_price").field("price");
- // ***按颜色分组后添加到子聚合计算
- popularColorAggs.subAggregation(priceAggs);
-
- sourceBuilder.aggregation(popularColorAggs)
大多数情况下,数据都是简单的JSON对象,但是如果我们存入的ES数据比较复杂,包含对象。Lucene是不支持对象数据的,因此ES会将数据扁平化处理。
这时候需要引入一个特殊的对象,nested类型,它允许包含一组属性类似object数组的每个对象,可以被独立的搜索,互不影响。
- PUT my_index
- {
- "mappings": {
- "properties": {
- "user": {
- "type": "nested",
- "properties": {
- "first":{"type":"keyword"},
- "last":{"type":"keyword"}
- }
- }
- }
- }
- }
Suggester包含三种不同方式,用的Completion模式,实现自动补全和基于上下文的提示功能
1.创建一个articles的索引库,含有suggestion的字段,类型为completion
- PUT articles
- {
- "mappings": {
- "properties": {
- "suggestion":{
- "type": "completion"
- }
- }
- }
- }
组词分词器analyzer
- PUT /goods
- {
- "settings": {
- "analysis": {
- "analyzer": {
- "my_pinyin": {
- "tokenizer": "ik_smart",
- "filter": [
- "py"
- ]
- }
- },
- "filter": {
- "py": {
- "type": "pinyin",
- "keep_full_pinyin": false,
- "keep_joined_full_pinyin": true,
- "keep_original": true,
- "limit_first_letter_length": 16,
- "remove_duplicated_term": true
- }
- }
- }
- },
- "mappings": {
- "properties": {
- "id": {
- "type": "keyword"
- },
- "name": {
- "type": "completion",
- "analyzer": "my_pinyin",
- "search_analyzer": "ik_smart"
- },
- "title":{
- "type": "text",
- "analyzer": "my_pinyin",
- "search_analyzer": "ik_smart"
- },
- "price":{
- "type": "long"
- }
- }
- }
- }
- <!--elastic客户端-->
- <dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-high-level-client</artifactId>
- <version>7.4.2</version>
- </dependency>
- <!--日志-->
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core</artifactId>
- <version>2.11.2</version>
- </dependency>
- <?xml version="1.0" encoding="UTF-8"?>
- <Configuration status="WARN">
- <Appenders>
- <Console name="Console" target="SYSTEM_OUT">
- <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
- </Console>
- </Appenders>
- <Loggers>
- <Root level="error">
- <AppenderRef ref="Console"/>
- </Root>
- </Loggers>
- </Configuration>
- /**
- * 演示自动补全查询
- */
- @Test
- public void testSuggest() throws IOException {
- // 1.创建 查询条件工厂(封装查询条件) 的对象
- SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
-
- // 1.1.准备Suggest,需要指定四个内容:
- // 1)自动补全的名称:name_suggest
- // 2)自动补全的类型:SuggestBuilders.completionSuggestion
- // 3)自动补全的字段:completionSuggestion("name")
- // 4)自动补全的前缀:.prefix("s")
- SuggestBuilder suggestBuilder = new SuggestBuilder();
- suggestBuilder.addSuggestion("name_suggest",
- SuggestBuilders.completionSuggestion("name").prefix("s").size(30));
-
- // 1.2.添加suggest条件
- searchSourceBuilder.suggest(suggestBuilder);
-
-
- // 2.构建 搜索的请求 对象,把sourceBuilder放进去
- SearchRequest request = new SearchRequest("goods");
- request.source(searchSourceBuilder);
-
- // 3.发请求
- SearchResponse response = client.search(request, RequestOptions.DEFAULT);
-
- // 4.解析结果
- Suggest suggest = response.getSuggest();
-
- // 4.1.根据名称获取suggest结果
- Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> nameSuggest =
- suggest.getSuggestion("name_suggest");
- // 4.2.遍历结果
- nameSuggest.forEach(suggestion -> {
- // 获取其中的options
- List<? extends Suggest.Suggestion.Entry.Option> options = suggestion.getOptions();
- System.out.println("补全的结果如下: ");
- // 遍历options
- for (Suggest.Suggestion.Entry.Option option : options) {
- Text text = option.getText();
- System.out.println("\t" + text);
- }
- });
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。