ElasticSearch知识笔记

这篇具有很好参考价值的文章主要介绍了ElasticSearch知识笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

ElasticSearch笔记


  • Typora

1. Kibana操作ES
# 1. 索引index的相关操作
# 查看es中的索引类型
GET /_cat/indices?v

# 创建索引
PUT /products

# 指定索引的分片信息
PUT /orders
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  }
}

# 删除索引
DELETE /ems
DELETE /products


# 2. 映射(mapping)的相关操作
# 映射用于决定文档(document)中字段、类型等
# 数据类型
# 文本类型:keyword(不分词,关键字,关键词)
#           text(分词,文本内容)
# 数字类型:integer,long
# 小数类型: float, double
# 日期类型:date

# properties:指定索引中可以存放哪些字段信息
# mapping:指定文档的字段信息

# 创建商品索引并指定对应的字段信息
PUT /products
{
  "settings": {
    "number_of_shards": 1, 
    "number_of_replicas": 0
  },
  "mappings": {
    "properties": {  
      "id": {"type": "integer"},
      "title":{"type": "keyword"},
      "price":{"type": "double"},
      "created_at":{"type": "date"},
      "description":{"type": "text"}
    }
  }
}

# 通过使用索引和文档可以指定当前索引集合中存在的是一组数据类型相同的文档信息
# 文档就是一条条的数据信息

# 查询索引的信息
GET /_cat/indices?v

# 查看具体的映射信息
# 映射信息不能修改,只能进行删除
GET /products/_mapping


# 3.文档(document)的相关操作
# 添加一条文档信息
# 指定文档的id
POST /products/_doc/1
{
  "id":1,
  "title":"小浣熊",
  "price":2.2,
  "description":"小浣熊真的很好吃",
  "created_at":"2022-04-16"
}


# 不指定文档的id,那么id将会随机生成
POST /products/_doc/
{ 
  "title":"干脆面",
  "price":2.7,
  "description":"干脆面的味道比较一般",
  "created_at":"2022-04-16"
}

# 查询创建的文档信息,基于id的查询
GET /products/_doc/1



# 更新文档(会删除原始的文档信息,然后重新进行添加)
PUT /products/_doc/gXhKMoABJrsa4hAiaIzd
{
  "title":"日本豆"
}

# 查询
GET /products/_doc/gXhKMoABJrsa4hAiaIzd

# 更新文档,基于指定的字段进行更新,不会删除原文档信息
POST /products/_doc/1/_update
{
  "doc": {
    "price":1.9 
  }
}

# 查询
GET /products/_doc/1

# 删除指定的文档信息
DELETE /products/_doc/gXhKMoABJrsa4hAiaIzd

# 批量进行添加文档信息:_bulk
POST /products/_doc/_bulk
{"index":{"_id":"2"}}
  {"id":2,"title":"火鸡面","price":5.7,"description":"火鸡面比较上火","created_at":"2022-04-13"}
{"index":{"_id":"3"}}
  {"id":3,"title":"黄焖鸡","price":20.07,"description":"黄焖鸡的味道非常的nice","created_at":"2022-04-121"}

# 查询
GET /products/_doc/2



# 高级查询
# query DSL

# match_all:表示查询所有的文档信息
# _search: 后面添加的是json形式的数据信息
GET /products/_doc/_search
{
  "query":{  
    "match_all":{}
  }
}


# 查询所有的文档信息
GET /products/_search
{
  "query": {
    "match_all": {}
  }
}


# 多字段进行匹配,并指定每页返回的size,排序的字段选择以及先后的次序
# 选择高亮的字段,
GET /discusspost/_search
{
  "query":{
    "multi_match": {
      "query": "互联网",  # 表示当前的查询关键词,
      "fields": ["title", "content"] # 在哪些字段上进行查询
    }
  },
  "from": 0, # 起始页
  "size": 2, # 每页的size大小
  "sort": [  # 执行排序的字段选择,以及排序的先后次序
    {
      "type": {
        "order": "desc"
      }, 
      "score": {
        "order": "desc"
     },
     "createTime": {
       "order": "desc"
     }
    }
  ],
  "highlight": {  # 高亮的字段显示
  "require_field_match": "false",
    "pre_tags": ["<em>"], 
    "post_tags": ["</em>"],
    "fields": {"title": {}, "content": {}}  # 在哪些字段上进行显示高亮
  }
}



# 查询索引的映射信息
GET /products/_mapping


# term:基于关键词的查询
# 根据价格进行查询
GET /products/_search
{
  "query": {
    "term": {
      "price": {
        "value": 2.7
      }
    }
  }
}

# 根据title进行查询,title的类型为text
# keyword,integer,double等:不分词,则表示为全部内容搜索(精确查询)
# text类型:使用标准的分词器(所以只能是根据单字进行查询),中文单字分词,英文是空格分词,只有text类型的字段才会进行分词

GET /products/_search
{
  "query": {
    "term": {
      "title": {
        "value": "面"
      }
    }
  }
}

# 查询
GET /products/_search
{
  "query": {
    "term": {
      "id": {
        "value": 2
      }
    }
  }
}


# range范围查询
# range关键字:用来查询指定范围内的文档信息
GET /products/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 1,
        "lte": 10
      }
    }
  }
}


# prefix:前缀查询
# 用来检索含有指定前缀关键词的相关文档信息
GET /products/_search
{
  "query": {
    "prefix": {
      "title": {
        "value": "火"
      }
    }
  }
}


# wildcard:通配符查询
# ?:用来匹配一个任意的字符,*:用于匹配多个任意符
GET /products/_search
{
  "query": {
    "wildcard": {
      "description": {
        "value": "较*"
      }
    }
  }
}

# ids: 多id进行查询
# ids:值为数组类型,用来根据一组id获取多个对应的文档
GET /products/_search
{
  "query": {
    "ids": {
      "values": ["2", "gHhIMoABJrsa4hAim4xr"]
    }
  }
}


# fuzzy:模糊查询
# 用来模糊查询含有指定关键字的文档
GET /products/_search
{
  "query": {
    "fuzzy": {
      "title": "火鸡"
    }
  }
}


# bool: 布尔查询
# 用来组合多个条件实现复杂查询
# must:相当于&&同时成立
# should:相当于||成立一个就行
# must_not:相当于 !不能满足于任何一个
GET /products/_search
{
  "query": {
    "bool": {
      "must": [
        {"term": {
          "price": {
            "value": "2.7"
          }
        }}
      ]
    }
  }
}

# 组合的方式进行查询
GET /products/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "ids": {
            "values": [2]
          }
        },
        {
          "term": {
            "title": {
              "value": "小"
            }
          }
        }
      ]
    }
  }
}



# multi_match: 多字段查询
GET /products/_search
{
  "query": {
    "multi_match": {
      "query": "小浣熊",  # 要查询的字段内容
      "fields": ["title", "description"]  # 指定在哪些字段上进行查询
    }
  }
}
# 注意:字段类型分词,将查询条件分词之后进行查询改字段,如果该字段不分词就会将查询条件作为整体进行查询


# query_string: 默认字段分词查询
# 注意:将查询字段就查询条件进行分词查询,查询字段不分词将查询条件不分词查询
GET /products/_search
{
  "query": {
    "query_string": {
      "default_field": "description",
      "query": "比较好吃"
    }
  }
}


# highlight:高亮显示
GET /products/_search
{
  "query": {
    "query_string": {
      "default_field": "description",
      "query": "浣熊"
    }
  },
  "highlight": {
    "pre_tags": ["<span style='color:red;'>"],
    "post_tags": ["</span>"],
    "require_field_match": "false", 
    "fields": {
      "*":{}
    }
  },
  "size": 2,
  "from": 0,
  "sort": [
    {
      "price": { 
        "order": "desc"
      }
    }
  ],
  "_source": [
      "price","title","description"
    ]
}
# 倒排索引的查询
DELETE /products


# 创建新的索引,并指定映射的规则
PUT /products
{
  "mappings": {
    "properties": {
      "description":{
        "type": "text"
      },
      "price":{
        "type": "float"
      },
      "title":{
        "type": "keyword"
      }
    }
  }
}

# 查看具体的索引规则
GET /products/_mapping

# 批量添加数据信息
PUT /products/_doc/_bulk
{"index":{"_id":1}}
{"title":"蓝月亮洗衣液","price":19.9, "description":"蓝月亮洗衣液很高效"}
{"index":{"_id":2}}
{"title":"iphone13","price":19.9, "description":"很不错的手机"}
{"index":{"_id":3}}
{"title":"小浣熊干脆面","price":1.5, "description":"小浣熊很好吃"}


# 查询所有的文档信息
GET /products/_search
{
  "query": {
    "match_all": {}
  }
}

# 关键字查询
GET /products/_search
{
  "query": {
    "term": {
      "description": {
        "value": "不"
      }
    }
  }
}


# 内置分词器
# Standard analyzer:默认分词器,英文按照单词进行切分,并小写处理
# Simple analyzer:按照单词切分(符号被过滤),小写处理
# stop analyzer: 小写处理,停用词过滤
# whilespace analyzer:按照空格切分,不转小写
# keyword analyzer:不分词,直接将输入当做输出

# standard分词器
# 中文按照空格进行分词,大写转小写
POST /_analyze
{
  "analyzer": "standard",
  "text":"this is a , good MAN 北京香山公园"
}

# simple 分词器,中文按照空格进行分词
# 
POST /_analyze
{
  "analyzer": "simple",
  "text": "this is a , good man 北京香山公园"
}

# whiteSpace 分词器,中文按照空格进行分词
# 
POST /_analyze
{
  "analyzer": "whitespace",
  "text": "this is a , good man 北京香山公园"
}



# 创建索引的时候指定分词器
PUT /test
{
  "mappings": {
    "properties": {
      "title":{
        "type": "text",
        "analyzer": "standard"
      }
    }
  }
}

# 添加一条文档
PUT /test/_doc/1
{
  "title":"我是张三,this is a good MAN"
}

# 关键词查询(因为已经分词)
POST /test/_search
{
  "query": {
    "term": {
      "title": {
        "value": "a"
      }
    }
  }
}
# IK使用:有两种颗粒度的拆分
ik_smart:会做最粗细粒度的拆分
ik_max_word:会将文本做最细粒度的拆分
---------------------------------------------------

DELETE /test

# ik_smart
POST /_analyze
{
  "analyzer": "ik_smart",
  "text": "中国人民共和国"
}

# ik_max_word
POST /_analyze
{
  "analyzer": "ik_max_word",
  "text": "中国人民共和国"
}


# 使用ik_max_word分词器
PUT /test
{
  "mappings": {
    "properties": {
      "title":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}


# 添加一条文档
PUT /test/_doc/1
{
  "title":"我是张三,this is a good MAN"
}

GET /test/_search
{
  "query": {
    "term": {
      "title": {
        "value": "张三"
      }
    }
  }
}
2. 配置扩展词
  • IK支持自定义扩展词典和停用词典,所谓扩展词典就是有些词并不是关键词,但是也希望被ES用来作为检索的关键词,可以将这些词加入扩展词典。停用词典就是有些词是关键词,但是出于业务场景不想使用这些关键词被检索到,可以将这些词放入停用词典。

  • 如何定义扩展词典和停用词典可以修改IK分词器中config目录中IKAnalyzer.cfg.xml这个文件。

  • NOTE:词典的编码必须为UTF-8,否则无法生效文章来源地址https://www.toymoban.com/news/detail-504155.html

1. 修改vim IKAnalyzer.cfg.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
    <properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--用户可以在这里配置自己的扩展字典 -->
        <entry key="ext_dict">ext_dict.dic</entry>
         <!--用户可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords">ext_stopword.dic</entry>
    </properties>

2. 在ik分词器目录下config目录中创建ext_dict.dic文件   编码一定要为UTF-8才能生效
	vim ext_dict.dic 加入扩展词即可

3. 在ik分词器目录下config目录中创建ext_stopword.dic文件 
	vim ext_stopword.dic 加入停用词即可

4. 重启es生效
3. 整合SpringBoot
/**
 * 配置完成后,会生成两个对象:
 *  1、ElasticSearchOperations
 *      特点:始终使用面向对象的方式进行操作
 *  2、RestHighLevelClient
 *      特点:
 *
 */

@Configuration
public class EsConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo("localhost:9200")
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}
/**
 *  概念;
 *      索引:用来存储相似文档的集合
 *      映射:用来决定放入文档的每个字段以什么样的方式录入到es中,可以指定字段类型,分词器
 *      文档:可以被索引的最小单元的json数据形式
 *
 * @Document: 代表当前对象是一个文档
 *      indexName:指定索引的名字
 *      createIndex:默认创建索引(索引不存在就进行创建)
 * @Id: 将对象id字段与es中的_id进行对应
 * @Field: 用来描述属性在es中存储类型以及分词的情况
 *      type:指定字段的类型
 */
@Document(indexName = "product", createIndex = true)
public class Product {

    @Id
    private Integer id;

    @Field(type = FieldType.Keyword)
    private String title;

    @Field(type = FieldType.Double)
    private Double price;

    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String description;
}
3.1 ElasticsearchOperations(不推荐)
@SpringBootTest
class EsApplicationTests {

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    /**
	 * save:索引一条文档,更新一条文档
	 * 	save方法当id不存在的时候,是添加文档操作
	 * 	当id存在时,是更新文档操作
	 */
    @Test
    public void testInsert(){
        Product product = new Product();
        product.setId(2);
        product.setTitle("干脆面");
        product.setPrice(1.9);
        product.setDescription("干脆面比较好吃,但是上火");
        elasticsearchOperations.save(product);
    }


    /**
	 * 查询文档信息
	 */
    @Test
    public void testSearch(){
        Product product = elasticsearchOperations.get("1", Product.class);
        System.out.println("product = " + product);
    }

    /**
	 * 查询所有的文档信息
	 */
    @Test
    public void tesSearch() throws JsonProcessingException {
        SearchHits<Product> productSearchHits = elasticsearchOperations.search(Query.findAll(), Product.class);
        System.out.println("总分数 = " + productSearchHits.getMaxScore());
        System.out.println("符合条件的总条数 = " + productSearchHits.getTotalHits());
        for (SearchHit<Product> productSearchHit : productSearchHits) {
            System.out.println(new ObjectMapper().writeValueAsString(productSearchHit.getContent()));
        }
    }

    /**
	 * 删除一条文档信息
	 */
    @Test
    public void testDelete(){
        Product product = new Product();
        product.setId(1);
        String delete = elasticsearchOperations.delete(product);
        System.out.println("delete = " + delete);
    }

    /**
	 * 删除所有
	 */
    @Test
    public void testDelAll(){
        elasticsearchOperations.delete(Query.findAll(), Product.class);
    }
}
3.2 RestHighLevelClient(推荐)
# 删除索引
DELETE /products

# 查看索引信息
GET /_cat/indices?v

# 查看索引的映射结构
GET /products/_mapping

# 删除索引信息
DELETE /products

# 创建索引并指定映射的类型
PUT /products
{
  "mappings": {
    "properties": {
      "title": {
        "type": "keyword"
      },
      "price":{
        "type": "double"
      },
      "created_at":{
        "type": "date"
      },
      "description":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}
  • 索引
/**
 * 对索引和映射的操作
 */
public class RestHighLevelClientIndexTest extends EsApplicationTests {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 创建索引并指定映射的类型
     * PUT /products
     * {
     *   "mappings": {
     *     "properties": {
     *       "title": {
     *         "type": "keyword"
     *       },
     *       "price":{
     *         "type": "double"
     *       },
     *       "created_at":{
     *         "type": "date"
     *       },
     *       "description":{
     *         "type": "text",
     *         "analyzer": "ik_max_word"
     *       }
     *     }
     *   }
     * }
     */
    @Test
    public void testCreateIndex() throws IOException {
        // 创建索引
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("products");
        // 创建映射
        createIndexRequest.mapping("{\n" +
                "    \"properties\": {\n" +
                "      \"title\": {\n" +
                "        \"type\": \"keyword\"\n" +
                "      },\n" +
                "      \"price\":{\n" +
                "        \"type\": \"double\"\n" +
                "      },\n" +
                "      \"created_at\":{\n" +
                "        \"type\": \"date\"\n" +
                "      },\n" +
                "      \"description\":{\n" +
                "        \"type\": \"text\",\n" +
                "        \"analyzer\": \"ik_max_word\"\n" +
                "      }\n" +
                "    }\n" +
                "  }", XContentType.JSON);
        // 创建索引
        CreateIndexResponse response = restHighLevelClient
                .indices()  // 表示对索引的操作
                .create(createIndexRequest, RequestOptions.DEFAULT);
        System.out.println(response.isAcknowledged());
        // 关闭
        restHighLevelClient.close();
    }

    /**
     * 删除索引
     * DELETE /products
     */
    @Test
    public void testDel() throws IOException {
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("products");
        AcknowledgedResponse response = restHighLevelClient.indices()
                .delete(deleteIndexRequest, RequestOptions.DEFAULT);
        System.out.println(response.isAcknowledged());
    }
}
  • 文档
/**
 * 对文档的操作
 * response:所有文档查询得到的response都是kiban中对应语句得到的json数据信息整体
 */
public class RestHighLevelClientDocumentTest extends EsApplicationTests {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

     /**
     * 过滤查询
     * query: 精确查询,查询计算文档的得分,并根据文档的得分尽心返回
     * filter query:过滤查询,用来在大量数据中筛选出本地查询的相关数据,不会计算文档得分,经常使用
     *              filter query 结果进行缓存
     * 注意:一旦使用query 和filter query, es会优先使用filter query,然后再使用query
     */
    @Test
    public void testFilter() throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery())
                .postFilter(QueryBuilders.rangeQuery("price").gt(0).lte(10)); // 指定过滤条件

        searchRequest.source(sourceBuilder);

        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println("记录总条数: " + response.getHits().getTotalHits().value);
        System.out.println("记录的最大得分: " + response.getHits().getMaxScore());

        // 所有的文档信息
        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit : hits) {
            System.out.println("id: " + hit.getId() + ",source: " + hit.getSourceAsString());
        }
    }
    
    /**
     * 分页查询:from:起始页, size:每页显示的记录数
     *         sort:排序
     *         _source: 返回指定的字段
     *         highlight: 高亮查询
     *
     * GET /products/_search
     * {
     *   "query":{
     *     "term": {
     *       "description": {
     *         "value": "好吃"
     *       }
     *     }
     *   },
     *   "from": 0,
     *   "size": 2,
     *   "sort": [
     *     {
     *       "price": {
     *         "order": "desc"
     *       }
     *     }
     *   ],
     *   "_source": ["price", "description"],
     *   "highlight": {
     *     "require_field_match": "false",
     *     "pre_tags": ["<span style='color:red;'>"],
     *     "post_tags": ["</span>"],
     *     "fields": {"description": {}}
     *   }
     * }
     */
    @Test
    public void testSearchAll() throws IOException {
        // 指定查询的索引
        SearchRequest searchRequest = new SearchRequest("products");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        // 创建高亮器
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        // 高亮的字段(只有类型为text的才能进行分词)
        highlightBuilder.requireFieldMatch(false).field("description").field("title")
                .preTags("<span style='color:red;'>")
                .postTags("</span>");
        // 查询条件拼接
        sourceBuilder.query(QueryBuilders.termQuery("description", "好吃"))
                .from(0) // 起始页
                .size(2) // 每页的大小
                .sort("price", SortOrder.DESC) // 排序规则
                .fetchSource(new String[]{}, new String[]{}) // 都是数组, 参数1:需要返回的字段(不填默认返回所有)  参数2:需要排序的字段
                .highlighter(highlightBuilder); // 高亮
        searchRequest.source(sourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println("记录总条数: " + response.getHits().getTotalHits().value);
        System.out.println("记录的最大得分: " + response.getHits().getMaxScore());

        // 所有的文档信息
        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit : hits) {
            System.out.println("id: " + hit.getId() + ",source: " + hit.getSourceAsString());

            // 获取高亮的字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (highlightFields.containsKey("description")){
                System.out.println("description 高亮的结果 " + highlightFields.get("description").getFragments());
            }
            if (highlightFields.containsKey("title")){
                System.out.println("description 高亮的结果 " + highlightFields.get("title").getFragments());
            }
        }
    }
    
    
    
    
     /**
     * 查询帖子
     * GET /discusspost/_search
     * {
     *   "query":{
     *     "multi_match": {
     *       "query": "互联网",
     *       "fields": ["title", "content"]
     *     }
     *   },
     *   "from": 0,
     *   "size": 2,
     *   "sort": [
     *     {
     *       "type": {
     *         "order": "desc"
     *       },
     *       "score": {
     *         "order": "desc"
     *      },
     *      "createTime": {
     *        "order": "desc"
     *      }
     *     }
     *   ],
     *   "highlight": {
     *   "require_field_match": "false",
     *     "pre_tags": ["<em>"],
     *     "post_tags": ["</em>"],
     *     "fields": {"title": {}, "content": {}}
     *   }
     * }
     * @throws IOException
     */
    @Test
    public void searchByRepository() throws IOException {
        // 构建查询对象
//        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
//                // 在哪些字段上查询指定的关键词
//                .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content"))
//                // 只当排序的方式,先按照类型,得分,创建时间进行排序
//                .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC))
//                .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC))
//                .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
//                // 指定返回的条数
//                .withPageable(PageRequest.of(0, 10))
//                // 哪些字段要显示高亮,并给需要高亮度的字段添加指定的前后缀
//                .withHighlightFields(
//                        new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
//                        new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")
//                ).build();
        // 设置需要查询的索引
        SearchRequest searchRequest = new SearchRequest("discusspost");
        // 构建查询的条件信息
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        // 高亮设置
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        // 设置需要在哪些字段中进行查询
        highlightBuilder.requireFieldMatch(false).field("title").field("content")
                .preTags("<em>")
                .postTags("</em>");
        // 拼接查询条件
        sourceBuilder.query(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content"))
                .from(0)
                .size(10)
                .sort("type", SortOrder.DESC)
                .sort("score", SortOrder.DESC)
                .sort("createTime", SortOrder.DESC)
                // 都是数组, 参数1:需要返回的字段(不填默认返回所有)  参数2:需要排序的字段
                .fetchSource(new String[]{}, new String[]{})
                .highlighter(highlightBuilder);
        // 将查询条件设置到查询请求中
        searchRequest.source(sourceBuilder);
        // 查询
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        // System.out.println("记录总条数: " + response.getHits().getTotalHits().value);
        // System.out.println("记录的最大得分: " + response.getHits().getMaxScore());

        // 所有的文档信息
        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit : hits) {
            // 如何
            // System.out.println("id: " + hit.getId() + ",source: " + hit.getSourceAsString());
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            sourceAsMap.remove("_class");
            // 获取高亮的字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (highlightFields.containsKey("content")){
                sourceAsMap.put("content", highlightFields.get("content").getFragments()[0].toString());
                // System.out.println("content 高亮的结果 " + highlightFields.get("content").getFragments()[0].toString());
            }
            if (highlightFields.containsKey("title")){
                sourceAsMap.put("title", highlightFields.get("title").getFragments()[0].toString());
                // System.out.println("title 高亮的结果 " + highlightFields.get("title").getFragments()[0].toString());
            }
            // System.out.println(sourceAsMap);
            DiscussPost discussPost = JSONObject.parseObject(JSONObject.toJSONString(sourceAsMap), DiscussPost.class);
            System.out.println("discussPost = " + discussPost);
        }
    
    
    /**
     * # 关键词查询
     * GET /products/_search
     * {
     *   "query": {
     *     "term": {
     *       "title": {
     *         "value": "小浣熊"
     *       }
     *     }
     *   }
     * }
     */
    @Test
    public void testSearchTerm() throws IOException {
        // 1.关键字查询
        // query(QueryBuilders.termQuery("title", "小浣熊"));
        // 2.range 范围查询
        // query(QueryBuilders.rangeQuery("price").gt(0).lte(10));
        // 3.prefix前缀查询
        // query(QueryBuilders.prefixQuery("title", "小浣"));
        // 4.wildcard 通配符查询 ? 一个字符, * 任意多个字符
        // query(QueryBuilders.wildcardQuery("title", "烤冷*"));
        // 5.ids 多个指定   id 查询
        // query(QueryBuilders.idsQuery().addIds("1").addIds("3"));
        // 6.multi_query 多字段查询
        // query(QueryBuilders.multiMatchQuery("好吃", "title","description"));
    }


    public void query(QueryBuilder queryBuilder) throws IOException {
        // 指定查询的索引
        SearchRequest searchRequest = new SearchRequest("products");
        // 构建查询对象
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        // 关键词查询
        // sourceBuilder.query(QueryBuilders.termQuery("price", 10));
        // sourceBuilder.query(QueryBuilders.termQuery("description", "浣熊"));
        sourceBuilder.query(queryBuilder);
        // 构建查询请求
        searchRequest.source(sourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        // 获取最大得分和总条数
        System.out.println("总条数 = " + response.getHits().getTotalHits().value);
        System.out.println("最大的得分 = " + response.getHits().getMaxScore());


        // 获取所有符合条件的文档信息
        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }


    /**
     * 查看所有的文档信息
     * GET /products/_search
     * {
     *   "query":{
     *     "match_all": {}
     *   }
     * }
     */
    @Test
    public void testMatchAll() throws IOException {
        // 指定查询的索引
        SearchRequest searchRequest = new SearchRequest("products");
        // 构建查询条件对象
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        // 指明查询所有
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        // 指明查询条件
        searchRequest.source(sourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        // 查询总条数以及最大得分
        System.out.println("总条数 = " + response.getHits().getTotalHits().value);
        System.out.println("最大得分 = " + response.getHits().getMaxScore());

        // 查询到的详细的文档信息
        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit : hits) {
            String id = hit.getId();
            System.out.println("id: " + id + " 文档内容: " + hit.getSourceAsString());
        }
    }


    /**
     * 基于id查询指定的文档信息
     * GET /products/_doc/1
     */
    @Test
    public void testGet() throws IOException {
        GetRequest getRequest = new GetRequest("products", "1");
        GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
        System.out.println("response.getId() = " + response.getId());
        System.out.println("source = " + response.getSourceAsString());
    }


    /**
     * 删除指定的文档
     * DELETE /products/_doc/2
     */
    @Test
    public void testDel() throws IOException {
        // 参数1: 删除请求对象,   参数2:请求配置对象
        DeleteResponse response =
                restHighLevelClient.delete(new DeleteRequest("products", "2"), RequestOptions.DEFAULT);
        System.out.println(response.status());
    }


    /**
     * 更新文档(原数据上更新)
     * POST /products/_doc/1/_update
     * {
     *   "doc": {
     *     "price":1.99
     *   }
     * }
     */
    @Test
    public void testUpdate() throws IOException {
        // 参数1:更新的是哪个索引的文档    参数2:更新的具体文档id
        UpdateRequest updateRequest = new UpdateRequest("products", "1");
        // doc()表示在原数据上进行修改信息
        updateRequest.doc("{\n" +
                "    \"price\":1.99\n" +
                "  }", XContentType.JSON);
        // 参数1:更新的请求对象    参数2:请求配置对象
        UpdateResponse response = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(response.status());
    }


    /**
     * 添加文档信息
     * POST /products/_doc/1
     * {
     * "title":"小浣熊",
     * "price":1.5,
     * "created_at":"2022-04-17",
     * "description":"小浣熊真的很好吃!"
     * }
     */
    @Test
    public void testCreate() throws IOException {
        // 指定在哪个索引下创建文档
        IndexRequest indexRequest = new IndexRequest("products");
        indexRequest
                .id("2") // 指定创建文档的id号
                .source("{\n" +
                        "  \"title\":\"干脆面\",\n" +
                        "  \"price\":2.0,\n" +
                        "  \"created_at\":\"2022-04-16\",\n" +
                        "  \"description\":\"干脆面好吃,但是比较上火!\"\n" +
                        "}", XContentType.JSON);
        // 参数1:索引请求对象,  参数2:请求配置对象
        IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        // 查看添加文档的状态
        System.out.println(response.status());
    }
}

到了这里,关于ElasticSearch知识笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 初识 Elasticsearch 应用知识,一文读懂 Elasticsearch 知识文集(3)

    🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论⭐收藏 🔎 Elasticsearch 领域知识 🔎 链接 专栏 Elasticsearch 专业知识学习一 Elasticsearch专栏

    2024年01月20日
    浏览(46)
  • 初识 Elasticsearch 应用知识,一文读懂 Elasticsearch 知识文集(4)

    🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论⭐收藏 🔎 Elasticsearch 领域知识 🔎 链接 专栏 Elasticsearch 专业知识学习一 Elasticsearch专栏

    2024年01月20日
    浏览(60)
  • 初识 Elasticsearch 应用知识,一文读懂 Elasticsearch 知识文集(5)

    🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论⭐收藏 🔎 Elasticsearch 领域知识 🔎 链接 专栏 Elasticsearch 专业知识学习一 Elasticsearch专栏

    2024年01月23日
    浏览(46)
  • 修改Typora字体,Typora页面美化

            hannotate是什么字体?hannotate sc regular字体又叫 手札体, 简称常规标准体,这款字体字形清秀工整,线条流畅洒脱,笔形富于变化。 下载地址:http://www.downyi.com/downinfo/51525.html         将压缩包解压后,直接把  华康手札体.ttf  文件复制到windows下的  C:WINDOW

    2024年02月08日
    浏览(40)
  • ElasticSearch基础知识汇总

    Elasticsearch是一个基于Lucene的搜索服务器。它提供了 一个分布式多用户能力的全文搜索引擎 , 基于RESTful web接口 。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠

    2024年02月11日
    浏览(44)
  • Elasticsearch系列-基础知识

    Elasticsearch是一个开源的分布式搜索和分析引擎,它能够快速地存储、搜索和分析大量的数据。 特点 分布式:Elasticsearch采用分布式架构,可以水平扩展,支持无缝添加节点,提高了系统的可用性和性能。 实时性:Elasticsearch能够实时地存储、搜索和分析数据,支持实时索引和

    2024年02月09日
    浏览(49)
  • ElasticSearch 知识归纳

    鱼弦:CSDN内容合伙人、CSDN新星导师、51CTO(Top红人+专家博主) 、github开源爱好者(go-zero源码二次开发、游戏后端架构 https://github.com/Peakchen) Elasticsearch 知识归纳: Elasticsearch 是一个基于开源的分布式搜索和分析引擎,建立在 Apache Lucene 库之上。它被广泛用于处理和分析大规模

    2024年02月08日
    浏览(36)
  • ElasticSearch知识体系详解

    ElasticSearch是基于Lucene的开源搜索及分析引擎,使用Java语言开发的搜索引擎库类,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。 它可以被下面这样准确的形容: 一个分布式的实时文档存储,每个字段可以被索引与搜索。 一个分布式实时分析搜索引

    2024年02月05日
    浏览(39)
  • Elasticsearch基础知识

    Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用Elasticsearch的水平伸缩性,能使数据在生产环境变得更有价值。Elasticsearch 的实现原理主要分为以下几个步骤,首先用户将数据提交到Elasticsea

    2024年02月02日
    浏览(36)
  • elasticsearch知识库

    es查询缓存 Elasticsearch的路由(Routing)特性 在Elasticsearch中,一个索引被分为多个分片,每个分片包含了部分索引数据。当我们进行查询时,Elasticsearch会将查询请求发送到每个分片上执行查询操作,然后将结果合并返回给客户端。 而路由查询是一种特殊的查询方式,它允许我

    2023年04月09日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包