ElasticSearch Java 使用

news/2025/1/20 8:55:35/文章来源:https://www.cnblogs.com/TMesh/p/18680708

目录
  • 创建工程,导入坐标
  • 创建索引 index
  • 创建映射 mapping
  • 建立文档 document
    • 建立文档(通过 XContentBuilder)
    • 建立文档(使用 Jackson 转换实体)
      • 1)添加jackson坐标
      • 2)创建 Article 实体
      • 3)代码实现
  • 查询文档操作
    • 关键词查询
    • 字符串查询
    • 使用文档 ID 查询文档
  • 查询文档分页操作
    • 批量插入数据
    • 分页查询
  • 查询结果高亮操作
    • 高亮显示的 html 分析
    • 高亮显示代码实现
  • Spring Data ElasticSearch
    • Spring Data
    • Spring Data ElasticSearch
      • SpringMvc
        • 1)导入 Spring Data ElasticSearch 坐标
        • 2)创建 applicationContext.xml 配置文件,引入 elasticsearch 命名空间
        • 3)编写实体 Article
        • 4)编写 Dao
        • 5)编写 Service
        • 6) 配置 applicationContext.xml
        • 7)配置实体
        • 8)创建测试类 SpringDataESTest
      • SpringBoot
        • 1)添加 maven 依赖
        • 2)配置 application.properties
        • 3)测试实体类
          • 方式一:继承 ElasticsearchRepository(适合简单查询)
            • 添加单个文档
            • 想自定义自己的 Repository 接口
          • 方式二:使用 ElasticsearchRestTemplate(更适合用于复杂查询)
            • 添加单个文档
            • 简单查询-通过 id
      • 常用查询命名规则
      • 查询方法测试
      • 1)dao 层实现
      • 2)service 层实现
      • 3)测试代码
      • 使用 Elasticsearch 的原生查询对象进行查询。

创建工程,导入坐标

pom.xml坐标

<dependencies><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>5.6.8</version></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>transport</artifactId><version>5.6.8</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-to-slf4j</artifactId><version>2.9.1</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.24</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.21</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>
</dependencies>

创建索引 index

@Test
//创建索引
public void test1() throws Exception{// 创建Client连接对象Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));//创建名称为blog2的索引client.admin().indices().prepareCreate("blog2").get();//释放资源client.close();
}


创建映射 mapping

@Test
//创建映射
public void test3() throws Exception{// 创建Client连接对象Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));// 添加映射/*** 格式:* "mappings" : {"article" : {"dynamic" : "false","properties" : {"id" : { "type" : "string" },"content" : { "type" : "string" },"author" : { "type" : "string" }}}}*/XContentBuilder builder = XContentFactory.jsonBuilder().startObject().startObject("article").startObject("properties").startObject("id").field("type", "integer").field("store", "yes").endObject().startObject("title").field("type", "string").field("store", "yes").field("analyzer", "ik_smart").endObject().startObject("content").field("type", "string").field("store", "yes").field("analyzer", "ik_smart").endObject().endObject().endObject().endObject();// 创建映射PutMappingRequest mapping = Requests.putMappingRequest("blog2").type("article").source(builder);client.admin().indices().putMapping(mapping).get();//释放资源client.close();
}


建立文档 document

建立文档(通过 XContentBuilder)

@Test
//创建文档(通过XContentBuilder)
public void test4() throws Exception{// 创建Client连接对象Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));//创建文档信息XContentBuilder builder = XContentFactory.jsonBuilder().startObject().field("id", 1).field("title", "ElasticSearch是一个基于Lucene的搜索服务器").field("content","它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。").endObject();// 建立文档对象/*** 参数一blog1:表示索引对象* 参数二article:类型* 参数三1:建立id*/client.prepareIndex("blog2", "article", "1").setSource(builder).get();//释放资源client.close();
}

建立文档(使用 Jackson 转换实体)

1)添加jackson坐标

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.8.1</version>
</dependency>
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.8.1</version>
</dependency>
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.8.1</version>
</dependency>

2)创建 Article 实体

public class Article {private Integer id;private String title;private String content;getter/setter...
}

3)代码实现

@Test
//创建文档(通过实体转json)
public void test5() throws Exception{// 创建Client连接对象Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));// 描述json 数据//{id:xxx, title:xxx, content:xxx}Article article = new Article();article.setId(2);article.setTitle("搜索工作其实很快乐");article.setContent("我们希望我们的搜索解决方案要快,我们希望有一个零配置和一个完全免费的搜索模式,我们希望能够简单地使用JSON通过HTTP的索引数据,我们希望我们的搜索服务器始终可用,我们希望能够一台开始并扩展到数百,我们要实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案。Elasticsearch旨在解决所有这些问题和更多的问题。");ObjectMapper objectMapper = new ObjectMapper();// 建立文档client.prepareIndex("blog2", "article", article.getId().toString())//.setSource(objectMapper.writeValueAsString(article)).get();.setSource(objectMapper.writeValueAsString(article).getBytes(), XContentType.JSON).get();//释放资源client.close();
}

查询文档操作

关键词查询

@Test
public void testTermQuery() throws Exception{//1、创建es客户端连接对象Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));//2、设置搜索条件SearchResponse searchResponse = client.prepareSearch("blog2").setTypes("article").setQuery(QueryBuilders.termQuery("content", "搜索")).get();//3、遍历搜索结果数据SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象System.out.println("查询结果有:" + hits.getTotalHits() + "条");Iterator<SearchHit> iterator = hits.iterator();while (iterator.hasNext()) {SearchHit searchHit = iterator.next(); // 每个查询对象System.out.println(searchHit.getSourceAsString()); // 获取字符串格式打印System.out.println("title:" + searchHit.getSource().get("title"));}//4、释放资源client.close();}

字符串查询

@Test
public void testStringQuery() throws Exception{//1、创建es客户端连接对象Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));//2、设置搜索条件SearchResponse searchResponse = client.prepareSearch("blog2").setTypes("article").setQuery(QueryBuilders.queryStringQuery("搜索")).get();//3、遍历搜索结果数据SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象System.out.println("查询结果有:" + hits.getTotalHits() + "条");Iterator<SearchHit> iterator = hits.iterator();while (iterator.hasNext()) {SearchHit searchHit = iterator.next(); // 每个查询对象System.out.println(searchHit.getSourceAsString()); // 获取字符串格式打印System.out.println("title:" + searchHit.getSource().get("title"));}//4、释放资源client.close();}

使用文档 ID 查询文档

@Testpublic void testIdQuery() throws Exception {//client对象为TransportClient对象SearchResponse response = client.prepareSearch("blog1").setTypes("article")//设置要查询的id.setQuery(QueryBuilders.idsQuery().addIds("test002"))//执行查询.get();//取查询结果SearchHits searchHits = response.getHits();//取查询结果总记录数System.out.println(searchHits.getTotalHits());Iterator<SearchHit> hitIterator = searchHits.iterator();while(hitIterator.hasNext()) {SearchHit searchHit = hitIterator.next();//打印整行数据System.out.println(searchHit.getSourceAsString());}}

查询文档分页操作

批量插入数据

 @Test
//批量插入100条数据
public void test9() throws Exception{// 创建Client连接对象Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));ObjectMapper objectMapper = new ObjectMapper();for (int i = 1; i <= 100; i++) {// 描述json 数据Article article = new Article();article.setId(i);article.setTitle(i + "搜索工作其实很快乐");article.setContent(i+ "我们希望我们的搜索解决方案要快,我们希望有一个零配置和一个完全免费的搜索模式,我们希望能够简单地使用JSON通过HTTP的索引数据,我们希望我们的搜索服务器始终可用,我们希望能够一台开始并扩展到数百,我们要实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案。Elasticsearch旨在解决所有这些问题和更多的问题。");// 建立文档client.prepareIndex("blog2", "article", article.getId().toString())//.setSource(objectMapper.writeValueAsString(article)).get();.setSource(objectMapper.writeValueAsString(article).getBytes(),XContentType.JSON).get();}//释放资源client.close();
}

分页查询

@Test
//分页查询
public void test10() throws Exception{// 创建Client连接对象Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));// 搜索数据SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog2").setTypes("article").setQuery(QueryBuilders.matchAllQuery());//默认每页10条记录// 查询第2页数据,每页20条//setFrom():从第几条开始检索,默认是0。//setSize():每页最多显示的记录数。searchRequestBuilder.setFrom(0).setSize(5);SearchResponse searchResponse = searchRequestBuilder.get();SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象System.out.println("查询结果有:" + hits.getTotalHits() + "条");Iterator<SearchHit> iterator = hits.iterator();while (iterator.hasNext()) {SearchHit searchHit = iterator.next(); // 每个查询对象System.out.println(searchHit.getSourceAsString()); // 获取字符串格式打印System.out.println("id:" + searchHit.getSource().get("id"));System.out.println("title:" + searchHit.getSource().get("title"));System.out.println("content:" + searchHit.getSource().get("content"));System.out.println("-----------------------------------------");}//释放资源client.close();
}

查询结果高亮操作

在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮

高亮显示的 html 分析

通过开发者工具查看高亮数据的 html 代码实现:

ElasticSearch 可以对查询出的内容中关键字部分进行标签和样式的设置,但是你需要告诉ElasticSearch 使用什么标签对高亮关键字进行包裹

高亮显示代码实现

@Test
//高亮查询
public void test11() throws Exception{// 创建Client连接对象Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));// 搜索数据SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog2").setTypes("article").setQuery(QueryBuilders.termQuery("title", "搜索"));//设置高亮数据HighlightBuilder hiBuilder=new HighlightBuilder();hiBuilder.preTags("<font style='color:red'>");hiBuilder.postTags("</font>");hiBuilder.field("title");searchRequestBuilder.highlighter(hiBuilder);//获得查询结果数据SearchResponse searchResponse = searchRequestBuilder.get();//获取查询结果集SearchHits searchHits = searchResponse.getHits();System.out.println("共搜到:"+searchHits.getTotalHits()+"条结果!");//遍历结果for(SearchHit hit:searchHits){System.out.println("String方式打印文档搜索内容:");System.out.println(hit.getSourceAsString());System.out.println("Map方式打印高亮内容");System.out.println(hit.getHighlightFields());System.out.println("遍历高亮集合,打印高亮片段:");Text[] text = hit.getHighlightFields().get("title").getFragments();for (Text str : text) {System.out.println(str);}}//释放资源client.close();
}

Spring Data ElasticSearch

Spring Data

Spring Data是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷,并支持map-reduce框架和云计算数据服务。 Spring Data可以极大的简化JPA的写法,可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了CRUD外,还包括如分页、排序等一些常用的功能。
Spring Data的官网:http://projects.spring.io/spring-data/
Spring Data常用的功能模块如下:

Spring Data ElasticSearch

Spring Data ElasticSearch 基于 spring data API 简化 elasticSearch操作,将原始操作elasticSearch的客户端API 进行封装 。Spring Data为Elasticsearch项目提供集成搜索引擎。Spring Data Elasticsearch POJO的关键功能区域为中心的模型与Elastichsearch交互文档和轻松地编写一个存储库数据访问层。
官方网站:http://projects.spring.io/spring-data-elasticsearch/

SpringMvc

1)导入 Spring Data ElasticSearch 坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itheima</groupId><artifactId>itheima_elasticsearch_demo3</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>5.6.8</version></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>transport</artifactId><version>5.6.8</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-to-slf4j</artifactId><version>2.9.1</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.24</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.21</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.8.1</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.8.1</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.8.1</version></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-elasticsearch</artifactId><version>3.0.5.RELEASE</version><exclusions><exclusion><groupId>org.elasticsearch.plugin</groupId><artifactId>transport-netty4-client</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.4.RELEASE</version></dependency></dependencies></project>

2)创建 applicationContext.xml 配置文件,引入 elasticsearch 命名空间

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/data/elasticsearchhttp://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd"></beans>

3)编写实体 Article

package com.domain;public class Article {private Integer id;private String title;private String content;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}@Overridepublic String toString() {return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";}}

4)编写 Dao

package com.dao;import com.domain.Article;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;@Repository
public interface ArticleRepository extends ElasticsearchRepository<Article, Integer> {}

5)编写 Service

package com.service;import com.domain.Article;public interface ArticleService {public void save(Article article);}
package com.service.impl;import com.dao.ArticleRepository;
import com.domain.Article;
import com.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class ArticleServiceImpl implements ArticleService {@Autowiredprivate ArticleRepository articleRepository;public void save(Article article) {articleRepository.save(article);}}

6) 配置 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/data/elasticsearchhttp://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd"><!-- 扫描Dao包,自动创建实例 --><elasticsearch:repositories base-package="com.dao"/><!-- 扫描Service包,创建Service的实体 --><context:component-scan base-package="com.service"/><!-- 配置elasticSearch的连接 --><!-- 配置elasticSearch的连接 --><elasticsearch:transport-client id="client" cluster-nodes="localhost:9300" cluster-name="my-elasticsearch"/><!-- ElasticSearch模版对象 --><bean id="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate"><constructor-arg name="client" ref="client"></constructor-arg></bean> 
</beans>

7)配置实体

基于 spring data elasticsearch 注解配置索引、映射和实体的关系

package com.domain;import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;//@Document 文档对象 (索引信息、文档类型 )
@Document(indexName="blog3",type="article")
public class Article {//@Id 文档主键 唯一标识@Id//@Field 每个文档的字段配置(类型、是否分词、是否存储、分词器 )@Field(store=true, index = false,type = FieldType.Integer)private Integer id;@Field(index=true,analyzer="ik_smart",store=true,searchAnalyzer="ik_smart",type = FieldType.text)private String title;@Field(index=true,analyzer="ik_smart",store=true,searchAnalyzer="ik_smart",type = FieldType.text)private String content;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}@Overridepublic String toString() {return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";}}
其中,注解解释如下:
@Document(indexName="blob3",type="article"):indexName:索引的名称(必填项)type:索引的类型
@Id:主键的唯一标识
@Field(index=true,analyzer="ik_smart",store=true,searchAnalyzer="ik_smart",type = FieldType.text)index:是否设置分词analyzer:存储时使用的分词器searchAnalyze:搜索时使用的分词器store:是否存储type: 数据类型

8)创建测试类 SpringDataESTest

package com.test;import com.domain.Article;
import com.service.ArticleService;
import org.elasticsearch.client.transport.TransportClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class SpringDataESTest {@Autowiredprivate ArticleService articleService;@Autowiredprivate TransportClient client;@Autowiredprivate ElasticsearchTemplate elasticsearchTemplate;/**创建索引和映射*/@Testpublic void createIndex(){elasticsearchTemplate.createIndex(Article.class);elasticsearchTemplate.putMapping(Article.class);}/**测试保存文档*/@Testpublic void saveArticle(){Article article = new Article();article.setId(100);article.setTitle("测试SpringData ElasticSearch");article.setContent("Spring Data ElasticSearch 基于 spring data API 简化 elasticSearch操作,将原始操作elasticSearch的客户端API 进行封装 \n" +"    Spring Data为Elasticsearch Elasticsearch项目提供集成搜索引擎");articleService.save(article);}}
public interface ArticleService {//保存public void save(Article article);//删除public void delete(Article article);//查询全部public Iterable<Article> findAll();//分页查询public Page<Article> findAll(Pageable pageable);}
import com.dao.ArticleRepository;
import com.domain.Article;
import com.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;@Service
public class ArticleServiceImpl implements ArticleService {@Autowiredprivate ArticleRepository articleRepository;public void save(Article article) {articleRepository.save(article);}public void delete(Article article) {articleRepository.delete(article);}public Iterable<Article> findAll() {Iterable<Article> iter = articleRepository.findAll();return iter;}public Page<Article> findAll(Pageable pageable) {return articleRepository.findAll(pageable);}
}
import com.domain.Article;
import com.service.ArticleService;
import org.elasticsearch.client.transport.TransportClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class SpringDataESTest {@Autowiredprivate ArticleService articleService;@Autowiredprivate TransportClient client;@Autowiredprivate ElasticsearchTemplate elasticsearchTemplate;/**创建索引和映射*/@Testpublic void createIndex(){elasticsearchTemplate.createIndex(Article.class);elasticsearchTemplate.putMapping(Article.class);}/**测试保存文档*/@Testpublic void saveArticle(){Article article = new Article();article.setId(100);article.setTitle("测试SpringData ElasticSearch");article.setContent("Spring Data ElasticSearch 基于 spring data API 简化 elasticSearch操作,将原始操作elasticSearch的客户端API 进行封装 \n" +"    Spring Data为Elasticsearch Elasticsearch项目提供集成搜索引擎");articleService.save(article);}/**测试保存*/@Testpublic void save(){Article article = new Article();article.setId(1001);article.setTitle("elasticSearch 3.0版本发布");article.setContent("ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口");articleService.save(article);}/**测试更新*/@Testpublic void update(){Article article = new Article();article.setId(1001);article.setTitle("elasticSearch 3.0版本发布...更新");article.setContent("ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口");articleService.save(article);}/**测试删除*/@Testpublic void delete(){Article article = new Article();article.setId(1001);articleService.delete(article);}/**批量插入*/@Testpublic void save100(){for(int i=1;i<=100;i++){Article article = new Article();article.setId(i);article.setTitle(i+"elasticSearch 3.0版本发布..,更新");article.setContent(i+"ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口");articleService.save(article);}}/**分页查询*/@Testpublic void findAllPage(){Pageable pageable = PageRequest.of(1,10);Page<Article> page = articleService.findAll(pageable);for(Article article:page.getContent()){System.out.println(article);}}
}

SpringBoot

1)添加 maven 依赖

<!--spring boot 整合 elasticsearch -->
<!--不用填写具体版本,spring boot 会自动找与之适配的 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

2)配置 application.properties

旧版本

server.port=8091spring.elasticsearch.rest.uris=http://127.0.0.1:9200
spring.elasticsearch.rest.username=elastic
spring.elasticsearch.rest.password=1234567

新版本(去掉了 rest)

server.port=8091spring.elasticsearch.uris=http://127.0.0.1:9200
spring.elasticsearch.username=elastic
spring.elasticsearch.password=1234567

3)测试实体类

创建一个员工的实体类
关键注解 @Document、@Id、@Field

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;import java.math.BigDecimal;
import java.util.Date;/*** 员工实体类* @Document:作用在类上,标记实体类为文档对象。 indexName(索引名称,相当于数据库的表名称)* @Id:作用在成员变量上,标记一个字段作为id主键。 在Elasticsearch中,文档ID是唯一的,用于标识文档。* @Field:定义Java对象属性与Elasticsearch文档字段之间的映射关系。* @author*/
@Document(indexName = "employee_info")
public class EmployeeInfo {@Idprivate Long id;/*** 工号*/@Field(name = "job_no")private String jobNo;/*** 姓名*/@Field(name = "name")private String name;/*** 英文名*/@Field(name = "english_name")private String englishName;/*** 工作岗位*/private String job;/*** 性别*/private Integer sex;/*** 年龄*/private Integer age;/*** 薪资*/private BigDecimal salary;/*** 入职时间*/@Field(name = "job_day", format = DateFormat.date_time)private Date jobDay;/*** 备注*/private String remark;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getJobNo() {return jobNo;}public void setJobNo(String jobNo) {this.jobNo = jobNo;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEnglishName() {return englishName;}public void setEnglishName(String englishName) {this.englishName = englishName;}public String getJob() {return job;}public void setJob(String job) {this.job = job;}public Integer getSex() {return sex;}public void setSex(Integer sex) {this.sex = sex;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public BigDecimal getSalary() {return salary;}public void setSalary(BigDecimal salary) {this.salary = salary;}public Date getJobDay() {return jobDay;}public void setJobDay(Date jobDay) {this.jobDay = jobDay;}public String getRemark() {return remark;}public void setRemark(String remark) {this.remark = remark;}public EmployeeInfo() {}public EmployeeInfo(Long id, String jobNo, String name, String englishName, String job, Integer sex, Integer age, BigDecimal salary, Date jobDay, String remark) {this.id = id;this.jobNo = jobNo;this.name = name;this.englishName = englishName;this.job = job;this.sex = sex;this.age = age;this.salary = salary;this.jobDay = jobDay;this.remark = remark;}@Overridepublic String toString() {return "EmployeeInfo{" +"id=" + id +", jobNo='" + jobNo + '\'' +", name='" + name + '\'' +", englishName='" + englishName + '\'' +", job='" + job + '\'' +", sex=" + sex +", age=" + age +", salary=" + salary +", jobDay=" + jobDay +", remark='" + remark + '\'' +'}';}
}
方式一:继承 ElasticsearchRepository(适合简单查询)

ElasticsearchRepository 提供了一个高级的抽象,使得你可以在不编写任何实现代码的情况下,直接使用预定义的 CRUD 方法和查询方法。
业务层接口继承 ElasticsearchRepository 类
泛型的参数分别是实体类型和主键类型
例如:

public interface EmployeeInfoRepository extends ElasticsearchRepository<EmployeeInfo, Long> {
}

然后就可以直接使用了

添加单个文档
import com.example.springbootfull.elasticsearch.bean.EmployeeInfo;
import com.example.springbootfull.elasticsearch.service.EmployeeInfoRepository;
import com.example.springbootfull.elasticsearch.service.EmployeeInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;@RestController
@RequestMapping("/employeeInfo")
public class EmployeeElasticController {@Autowiredprivate EmployeeInfoRepository elasticRepository;@RequestMapping("/save")public String save() throws Exception {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");EmployeeInfo employeeInfo = new EmployeeInfo(6001L, "2001", "张三", "zhangsan", "Java", 1, 19, new BigDecimal("12500.01"), simpleDateFormat.parse("2019-09-10"), "备注");elasticRepository.save(employeeInfo);return "success";}}
想自定义自己的 Repository 接口

就要遵守 自定义方法命名规范

【自定义方法命名约定】:

Keyword Sample Elasticsearch Query string
And findByNameAndPrice {"bool”[{"field” :{"name" :"?"}},{"field":{"price" :"?"}} ]}}:{must”::{"should" :[{"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
Or findByNameOrPrice {"bool”:{"must": {"field" : {"name" : "?"}}}}
Is findByName {"bool”:{"must": {"field" : {"name" : "?"}}}}
Not findByNameNot {"bool”:{"must_not": {"field" : {"name" : "?"}}}}
Between findByPriceBetween {"bool":{"must": {"range" : {"price" : {"from" : ?,"to" : ?,"include_ lower":true,"include_upper" :true}}}}}
LessThanEqual findByPriceLessThan {"bool": {"must":{"range" : {"price": {"from" : null,"to”: ?,"include_lower":true, "include_upper" : true}}}}}
GreaterThanEqual findByPriceGreaterThan {"bool":{"must":{"range” :{ price" : {"from": ?,"to”:null,"include_ lower:"true, "include_upper" : true}}}}}
Before findByPriceBefore {"bool":{"must":{"range” :{ price" : {"from": null,"to":?,"include_lower": true, "include_upper" : true}}}}}
After findByPriceAfter {"bool":{"must":{"range” :{ price” :{"from” :?."to”: null."include_ lower”:true,"include_upper":true}}}}}
Like findByNameLike {"bool":{"must”:{"field” :{"name":{"query" : "?*","analyze_wildcard" : true}}}}}
StartingWith findByNameStartingWith {"bool":{"must” :{"field” :{"name” :{"query" :"?*","analyze_wildcard" : true}}}}}
Endingwith findByNameEndingWith {"bool":{"must” :{"field” :{"name” :{"query" :"*?","analyze_wildcard" : true}}}}}
Contains/Containing findByNameContaining {"bool”:{"must":i"field” :{"name":{ query" :"?”,"analyze wildcard” : true}}}}}
In findByNameIn(Collection names) {"boo1":{"must”:{"bool” :{"should" :[{"field" : {"name" :"?"}}, {"field” : {"name"?"}}]}}}}
NotIn findByNameNotIn(Collecti
onnames)
{"bool": {"must not": {"bool": {"should": { field": {"name": "?"}}}}}}
Near findBvStoreNear Not Supported Yet !
True findBvAvailableTrue {"bool":{"must":{"field":{ "available":true}}}}
False findBvAvailableFalse {"bool":{"must":{"field":{ "available":false}}}}
OrderBy findByAvailableTrueOrderByNameDesc {"sort" : [{ "name":{"order" :"desc"} }],"bool":{"must" : {"field" : {"available":true}}}}

例如:我们来按照年龄区间查询,定义这样的一个方法findByAgeBetwee:

/*** 需要继承 ElasticsearchRepository 接口* 由于 Item 实体类中 id 为 Long 类型*/
public interface EmployeeInfoRepository extends ElasticsearchRepository<EmployeeInfo, Long>/*** 方法名必须遵守 SpringData 的规范* 年龄区间查询*/List<EmployeeInfo> findByAgeBetween(int age1, int age2);
}

然后,再通过 saveAll 新增多些数据,再进行自定义的方法进行查询

import com.example.springbootfull.elasticsearch.bean.EmployeeInfo;
import com.example.springbootfull.elasticsearch.service.EmployeeInfoRepository;
import com.example.springbootfull.elasticsearch.service.EmployeeInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;@RestController
@RequestMapping("/employeeInfo")
public class EmployeeElasticController {@Autowiredprivate EmployeeInfoRepository elasticRepository;@RequestMapping("/saveAll")public String saveAll() throws Exception {List<EmployeeInfo> list = new ArrayList<>();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");list.add(new EmployeeInfo(1001L, "2001", "张三", "zhangsan", "Java", 1, 19, new BigDecimal("12500.01"), simpleDateFormat.parse("2019-09-10"), "备注"));list.add(new EmployeeInfo(1002L, "2002", "李四", "lisi", "PHP", 1, 18, new BigDecimal("11600.01"), simpleDateFormat.parse("2019-09-10"), "备注"));list.add(new EmployeeInfo(1003L, "2003", "王五", "wangwu", "C++", 1, 20, new BigDecimal("9900.01"), simpleDateFormat.parse("2019-09-10"), "备注"));list.add(new EmployeeInfo(1004L, "2004", "赵六", "zhaoliu", "Java Leader", 1, 20, new BigDecimal("20000.01"), simpleDateFormat.parse("2019-09-10"), "备注"));list.add(new EmployeeInfo(1005L, "2005", "小五", "xiaowu", "H5", 1, 17, new BigDecimal("10600.01"), simpleDateFormat.parse("2019-09-10"), "备注"));list.add(new EmployeeInfo(1006L, "2006", "小六", "xaioliu", "web", 1, 20, new BigDecimal("12600.01"), simpleDateFormat.parse("2019-09-10"), "备注"));list.add(new EmployeeInfo(1007L, "2007", "小七", "xiaoqi", "app", 1, 22, new BigDecimal("20000.01"), simpleDateFormat.parse("2019-09-10"), "备注"));list.add(new EmployeeInfo(1008L, "2008", "小八", "xaioba", "Java", 1, 21, new BigDecimal("11000.01"), simpleDateFormat.parse("2019-09-10"), "备注"));list.add(new EmployeeInfo(1009L, "2009", "小九", "xiaojiu", "Java", 1, 20, new BigDecimal("14000.01"), simpleDateFormat.parse("2019-09-10"), "备注"));list.add(new EmployeeInfo(1010L, "2010", "大十", "dashi", "Java", 1, 20, new BigDecimal("13000.01"), simpleDateFormat.parse("2019-09-10"), "备注"));elasticRepository.saveAll(list);return "success -> " + list.size();}@RequestMapping("/findByAgeBetween")public String findByAgeBetween(){elasticRepository.findByAgeBetween(10,20);return "success";}}
方式二:使用 ElasticsearchRestTemplate(更适合用于复杂查询)

与 ElasticsearchRepository 相比,ElasticsearchRestTemplate 更适合用于复杂查询 。
比如 多个条件组合、范围查询、模糊查询、聚合查询等复杂场景
还支持分页、排序、过滤等高级功能

添加单个文档
@RestController
@RequestMapping("/employeeInfo")
public class EmployeeElasticController {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@RequestMapping("/template/save")public String  templateSave() throws Exception  {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");EmployeeInfo employeeInfo = new EmployeeInfo(8888L, "2001", "张八", "zhangsan", "Java", 1, 19, new BigDecimal("12500.01"), simpleDateFormat.parse("2019-09-10"), "备注");elasticsearchRestTemplate.save(employeeInfo);return "success";}
}
简单查询-通过 id
@RestController
@RequestMapping("/employeeInfo")
public class EmployeeElasticController {@Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;@RequestMapping("/getEmployeeInfo")public EmployeeInfo getEmployeeInfo() {return elasticsearchRestTemplate.get("6001", EmployeeInfo.class);}
}

常用查询命名规则

关键字 命名规则 解释 示例
and findByField1AndField2 根据Field1和Field2获得数据 findByTitleAndContent
or findByField1OrField2 根据Field1或Field2获得数据 findByTitleOrContent
is findByField 根据Field获得数据 findByTitle
not findByFieldNot 根据Field获得补集数据 findByTitleNot
between findByFieldBetween 获得指定范围的数据 findByPriceBetween
lessThanEqual findByFieldLessThan 获得小于等于指定值的数据 findByPriceLessThan

查询方法测试

1)dao 层实现

package com.dao;import com.domain.Article;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;public interface ArticleRepository extends ElasticsearchRepository<Article, Integer> {//根据标题查询List<Article> findByTitle(String condition);//根据标题查询(含分页)Page<Article> findByTitle(String condition, Pageable pageable);
}

2)service 层实现

public interface ArticleService {//根据标题查询List<Article> findByTitle(String condition);//根据标题查询(含分页)Page<Article> findByTitle(String condition, Pageable pageable);
}
package com.service.impl;import com.dao.ArticleRepository;
import com.domain.Article;
import com.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class ArticleServiceImpl implements ArticleService {@Autowiredprivate ArticleRepository articleRepository;public List<Article> findByTitle(String condition) {return articleRepository.findByTitle(condition);}public Page<Article> findByTitle(String condition, Pageable pageable) {return articleRepository.findByTitle(condition,pageable);}}

3)测试代码

package com.test;import com.domain.Article;
import com.service.ArticleService;
import org.elasticsearch.client.transport.TransportClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.List;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class SpringDataESTest {@Autowiredprivate ArticleService articleService;@Autowiredprivate TransportClient client;@Autowiredprivate ElasticsearchTemplate elasticsearchTemplate;/**条件查询*/@Testpublic void findByTitle(){String condition = "版本";List<Article> articleList = articleService.findByTitle(condition);for(Article article:articleList){System.out.println(article);}}/**条件分页查询*/@Testpublic void findByTitlePage(){String condition = "版本";Pageable pageable = PageRequest.of(2,10);Page<Article> page = articleService.findByTitle(condition,pageable);for(Article article:page.getContent()){System.out.println(article);}}}

使用 Elasticsearch 的原生查询对象进行查询。

@Test
public void findByNativeQuery() {//创建一个SearchQuery对象SearchQuery searchQuery = new NativeSearchQueryBuilder()//设置查询条件,此处可以使用QueryBuilders创建多种查询.withQuery(QueryBuilders.queryStringQuery("备份节点上没有数据").defaultField("title"))//还可以设置分页信息.withPageable(PageRequest.of(1, 5))//创建SearchQuery对象.build();//使用模板对象执行查询elasticsearchTemplate.queryForList(searchQuery, Article.class).forEach(a-> System.out.println(a));
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/871992.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IntelliJ IDEA 2024.3 Java开发工具

IntelliJ IDEA 2024.3 Java开发工具 JetBrains IntelliJ IDEA 2024 mac,是一款Java开发工具,IntelliJ IDEA 凭借无与伦比的 Java 和 Kotlin 支持脱颖而出。从一开始就支持尖IDEA 2024.3 中文版开发工具端语言功能,保持领先地位。IntelliJ IDEA 对您的代码了如指掌,利用这些…

AI应用实战课学习总结(6)分类算法分析实战

本文介绍了机器学习中的分类场景问题,常用的分类算法 以及 分类和回归的简单对比,最后通过一个医疗数据诊断分类的案例做了一次实战,相信对你理解分类应用应该有所帮助。大家好,我是Edison。 最近入坑黄佳老师的《AI应用实战课》,记录下我的学习之旅,也算是总结回顾。 今…

深入浅出索引(上)

1.什么是数据库索引,索引是干什么用的? 对于数据库的表而言,索引其实就是它的“目录”。 2.索引的三种实现方式?(暂时介绍3种) ①哈希表索引:哈希表是一种以键 - 值(key-value)存储数据的结构,我们只要输入待查找的值即 key,就可以找到其对应的值即 Value。哈希的思…

【推荐】一款开源且功能丰富、技术先进的在线项目任务管理系统

项目介绍 DooTask是一款基于PHP + Vue开源的、功能丰富、技术先进、安全性高的开源在线项目任务管理系统,适合各种规模的团队使用。提供各类文档协作工具、在线思维导图、在线流程图、项目管理、任务分发、即时IM,文件管理等工具;同时消息功能使用非对称加密技术让你的沟通更…

《SpringBoot》自动装配原理(简单易懂)

引入 先看SpringBoot的主配置类 @SpringBootApplication public class DemoApplication{public static void main(String[] args){SpringApplication.run(StartEurekaApplication.class, args);} }@SpringBootApplication 点进@SpringBootApplication来看,发现@SpringBootAppl…

VMware Data Services Manager 2.2 发布 - 数据库管理和数据服务管理

VMware Data Services Manager 2.2 发布 - 数据库管理和数据服务管理VMware Data Services Manager 2.2 发布 - 数据库管理和数据服务管理 在 vSphere 环境中按需配置和自动管理 PostgreSQL 和 MySQL 数据库 请访问原文链接:https://sysin.org/blog/vmware-data-services-mana…

PyMuPDF4LLM : 提取 PDF 数据的终结者

你知道处理 PDF 文件时会遇到什么,尤其是那些包含复杂研究内容或者有表格、图像和额外信息的文档。对于 AI 领域的人,特别是那些在调整大型语言模型(LLM)或构建知识检索系统(比如 RAG)的人来说,提取正确的数据非常重要。然而,老实说,并不是所有的 PDF 提取工具都能做到…

【Java开发】LLM实战:使用LangChain4j构建本地RAG系统

一、引言二、基本概念2.1 什么是RAG2.2 LangChain4j简介2.3 大模型开发 vs. 传统JAVA开发三、实战经验3.1 环境搭建3.1.1 向量库(Chroma)  3.1.2 集成LangChain4j3.2 程序编写3.2.1 项目结构3.2.2 知识采集3.2.3 文档切分  3.2.4 文本向量化3.2.5 向量…

3D NAND闪存技术的架构和工艺集成概述(下)

另一种具有FG的3D NAND结构是HC-FG结构,如图8a所示。与DC-SF结构不同,水平信道堆叠在HC-FG架构中;然而,单元格没有被CG包围。因此,FG单元可以通过沟道优先工艺堆叠,类似于传统的2D平面灰阵列,并且可以以低成本实现3D结构。此外,如图8b所示,HC-FG结构与层选择晶体管(L…

3D NAND闪存技术的架构和工艺集成概述(上)

Architecture and Process Integration Overview of 3D NAND Flash Technologies 3D NAND闪存技术的架构和工艺集成概述 摘要:在过去的几十年里,NAND闪存一直是最成功的非易失性存储技术之一,由于其高可扩展性和可靠的开关特性,它在电子设备中得到了广泛的应用。为了克服平…

推荐4本书《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》,谢谢

4本书推荐《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》由清华大学出版社资深编辑赵佳霓老师策划编辑的新书《AI芯片开发核心技术详解》已经出版,京东、淘宝天猫、当当等网上,相应陆陆续续可以购买。该…

【软件】解决奥林巴斯生物显微镜软件OlyVIA提示“不支持您使用的操作系统”安装中止的问题

【软件】解决奥林巴斯生物显微镜软件OlyVIA提示“不支持您使用的操作系统”安装中止的问题 零、问题 资源在文末 问题如下,从奥林巴斯生物显微镜软件官网下载地址:https://lifescience.evidentscientific.com.cn/zh/downloads/detail-iframe/?0[downloads][id]=847253920下载…