Java實(shí)現(xiàn)調(diào)用ElasticSearch?API的示例詳解
java操作es有兩種方式
1.通過(guò)操作es的9300端口,9300是tcp端口,集群節(jié)點(diǎn)之間通信也是通過(guò)9300端口,會(huì)通過(guò)9300和es建立一個(gè)長(zhǎng)連接,下面的es的依賴(lài)可以直接操作
但是隨著es的版本的提升spring-data需要封裝不同版本的es的jar包,好像還沒(méi)封裝到這個(gè)版本(2019),另外官方也不推薦通過(guò)9300來(lái)操作es,而且這種方式在es8以后將被廢棄
2.通過(guò)9200操作,發(fā)送http請(qǐng)求
- JestClient,非官方,更新慢
- RestTemplate(springboot),模擬發(fā)http請(qǐng)求,es很多操作需要自己封裝,麻煩
- HttpCLient,同上
- Elasticsearch-Rest-Client,官方RestClient,封裝了ES操作,API層次分明,上手簡(jiǎn)單
我們?cè)跒g覽官方文檔的時(shí)候發(fā)現(xiàn),js可以直接操作es,那為什么我們不直接用js來(lái)操作es呢?
- 出于安全,因?yàn)閑s集群屬于后端集群服務(wù)器,端口一般不對(duì)外暴露,如果對(duì)外暴露,會(huì)被別人惡意利用
- js對(duì)es支持度有些低,我們?nèi)绻胘s操作的話,不需要通過(guò)官網(wǎng)提供的api,我們直接發(fā)送ajax請(qǐng)求,用原生es語(yǔ)句即可
其中,官網(wǎng)的java api是通過(guò)9300來(lái)操作的,java rest api是通過(guò)9200來(lái)操作的
官網(wǎng)中有Java Low Level REST Client和Java High Level REST Client,關(guān)系就和mybatis和jdbc一樣
Elasticsearch-Rest-Client(官方,推薦)
這個(gè)不是專(zhuān)門(mén)看視頻學(xué)習(xí)的,是谷粒商城的時(shí)候,跟著老師敲的,所以其實(shí)就是一個(gè)對(duì)谷粒商城涉及到這塊兒的一個(gè)總結(jié),版本什么的自然也就是用的它的。
這算是我總結(jié)的一個(gè)api,沒(méi)有真實(shí)對(duì)照的使用過(guò),只是為了理清思路。
maven
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.atlinxi.gulimall</groupId>
<artifactId>gulimall-search</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gulimall-search</name>
<description>elasticsearch檢索服務(wù)</description>
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.4.2</elasticsearch.version>
<spring-cloud.version>2020.0.4</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>com.atlinxi.gulimall</groupId>
<artifactId>gulimall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置文件
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 spring.application.name=gulimall-search
es配置類(lèi)
package com.atlinxi.gulimall.search.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* es配置類(lèi),給容器中注入一個(gè)RestHighLevelClient
*/
@Configuration
public class GulimallElasticSearchConfig {
// 后端訪問(wèn)es的時(shí)候,出于安全考慮,可以攜帶一個(gè)請(qǐng)求頭
// 現(xiàn)在暫時(shí)不用
public static final RequestOptions COMMON_OPTIONS;
static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
// builder.addHeader("Authorization", "Bearer " + TOKEN);
// builder.setHttpAsyncResponseConsumerFactory(
// new HttpAsyncResponseConsumerFactory
// .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));
COMMON_OPTIONS = builder.build();
}
@Bean
public RestHighLevelClient esRestClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("192.168.56.10", 9200, "http")
// new HttpHost("localhost", 9201, "http")
));
return client;
}
}
導(dǎo)包
package com.atlinxi.gulimall.search; import com.alibaba.fastjson.JSON; import com.atlinxi.gulimall.search.config.GulimallElasticSearchConfig; import lombok.Data; import lombok.ToString; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.Avg; import org.elasticsearch.search.aggregations.metrics.AvgAggregationBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.io.IOException; @Autowired RestHighLevelClient restHighLevelClient;
查詢(xún)
// 1. 創(chuàng)建檢索請(qǐng)求
SearchRequest searchRequest = new SearchRequest();
// 2. 指定索引
searchRequest.indices("bank");
// 3. 指定DSL,檢索條件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 3.1 構(gòu)造檢索條件
// 所有的函數(shù)名都對(duì)應(yīng)原生es DSL語(yǔ)句
// searchSourceBuilder.query();
// searchSourceBuilder.from();
// searchSourceBuilder.size();
// searchSourceBuilder.aggregation();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.matchQuery("skuTitle", param.getKeyword()));
boolQuery.filter(QueryBuilders.termQuery("catalogId", param.getCatalog3Id()));
boolQuery.filter(QueryBuilders.termsQuery("brandId", param.getBrandId()));
BoolQueryBuilder nestedBoolQuery = QueryBuilders.boolQuery();
QueryBuilders.nestedQuery("attrs", nestedBoolQuery, ScoreMode.None);
boolQuery.filter(nestedQuery);
QueryBuilders.rangeQuery("skuPrice");
boolQuery.filter(rangeQuery);
searchSourceBuilder.query(QueryBuilders.matchQuery("address","mill"));
searchSourceBuilder.query(boolQuery);
searchSourceBuilder.sort(field, order);
sourceBuilder.from(0);
sourceBuilder.size(10);
HighlightBuilder builder = new HighlightBuilder();
builder.field("skuTitle");
builder.preTags("<b style='color:red'>");
builder.postTags("</b>");
sourceBuilder.highlighter(builder);
// 3.2 聚合
// 按照年齡的值分布進(jìn)行聚合
TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
// 計(jì)算平均薪資
AvgAggregationBuilder balanceAvg = AggregationBuilders.avg("balanceAvg").field("balance");
AggregationBuilders.nested("attr_agg", "attrs");
searchSourceBuilder.aggregation(balanceAvg);
searchSourceBuilder.aggregation(ageAgg);
// 4. 執(zhí)行檢索請(qǐng)求
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);
// 5.獲取響應(yīng)結(jié)果
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
searchHit.getSourceAsString();
// 3.1 獲取聚合結(jié)果
Aggregations aggregations = searchResponse.getAggregations();
Terms ageAgg1 = aggregations.get("ageAgg");
// 返回值為L(zhǎng)ist<? extends Terms.Bucket>
ageAgg1.getBuckets()
bucket.getKeyAsString();
aggregations.get("balanceAvg");保存更新
// 添加數(shù)據(jù)有多種方式,例如hashmap、直接將json粘在這兒
IndexRequest request = new IndexRequest("users");
request.id("1");
// request.source("userName","zhangsan","age",12,"gender","男");
// String jsonString = "{" +
// "\"user\":\"kimchy\"," +
// "\"postDate\":\"2013-01-30\"," +
// "\"message\":\"trying out Elasticsearch\"" +
// "}";
// request.source(jsonString, XContentType.JSON);
User user = new User();
user.setUserName("zs");
user.setAge(12);
user.setGender("man");
String jsonString = JSON.toJSONString(user);
request.source(jsonString, XContentType.JSON);
// 執(zhí)行保存/更新操作
IndexResponse index = restHighLevelClient.index(request, GulimallElasticSearchConfig.COMMON_OPTIONS);
// 批量保存
// 1. 建立索引 product 建立好映射關(guān)系(kibana操作)
// 2. 給es中保存這些數(shù)據(jù)
BulkRequest bulkRequest = new BulkRequest();
IndexRequest indexRequest = new IndexRequest(EsConstant.Product_INDEX);
indexRequest.id(skuEsModel.getSkuId().toString());
String s = JSON.toJSONString(skuEsModel);
indexRequest.source(s, XContentType.JSON);
bulkRequest.add(indexRequest);
BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);
// todo 如果批量錯(cuò)誤,處理錯(cuò)誤
boolean b = bulk.hasFailures();
bulk.getItems()
Spring Data ElasticSearch
Spring Data可以極大的簡(jiǎn)化JPA的寫(xiě)法,可以在幾乎不用寫(xiě)實(shí)現(xiàn)的情況下,實(shí)現(xiàn)對(duì)數(shù)據(jù)的訪問(wèn)和操作。除了CRUD外,還包括如分頁(yè)、排序等一些常用的功能。
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:es="http://www.springframework.org/schema/data/elasticsearch"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/elasticsearch
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd
">
<!--
如果你希望 進(jìn)一步了解 xsd相關(guān)的知識(shí) 請(qǐng)求百度去 百度不著了 http://www.jk1123.com/?p=124
-->
<!--
配置 client 連上 es
配置 dao層的掃描
配置其他 一個(gè)叫做 esTemplate 就是一個(gè)簡(jiǎn)單對(duì)應(yīng)client封裝
-->
<es:transport-client id="client" cluster-nodes="127.0.0.1:9300" cluster-name="my-elasticsearch"/>
<es:repositories base-package="com.itheima.dao"></es:repositories>
<bean id="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
<constructor-arg name="client" ref="client"></constructor-arg>
</bean>
</beans>實(shí)體類(lèi)
實(shí)體類(lèi)的無(wú)參構(gòu)造必須有,否則查詢(xún)出來(lái)的對(duì)象無(wú)法映射到實(shí)體類(lèi)
@Document(indexName=“blob3”,type=“article”):
- indexName:索引的名稱(chēng)(必填項(xiàng))
- type:索引的類(lèi)型
@Id:主鍵的唯一標(biāo)識(shí)
@Field(index=true,analyzer=“ik_smart”,store=true,searchAnalyzer=“ik_smart”,type = FieldType.text)
- analyzer:存儲(chǔ)時(shí)使用的分詞器
- searchAnalyze:搜索時(shí)使用的分詞器
- store:是否存儲(chǔ)
- type: 數(shù)據(jù)類(lèi)型
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 文檔對(duì)象 (索引信息、文檔類(lèi)型 )
@Document(indexName="test03",type="book")
public class Book {
//@Id 文檔主鍵 唯一標(biāo)識(shí)
@Id
//@Field 每個(gè)文檔的字段配置(類(lèi)型、是否分詞、是否存儲(chǔ)、分詞器 )
@Field(store = true, index = false, type = FieldType.Integer)
private Integer id;
@Field(analyzer = "ik_max_word", store = true, type = FieldType.text)
private String title;
@Field(analyzer = "ik_max_word", store = true, type = FieldType.text)
private String content;
@Field(index = false, store = true, type = FieldType.Long)
private Long sales;
dao
import com.itheima.domain.Book;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface BookDao extends ElasticsearchRepository<Book, Integer> {
// 除了系統(tǒng)自帶的方法,還可以自定義命名
List<Book> findByContent(String content);
List<Book> findByContentAndTitle(String content, String title);
Page<Book> findByContent(String content, Pageable pageable);
}
crud
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;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:beans.xml")
public class AppTest {
@Resource
private BookDao bookDao;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
// 創(chuàng)建索引庫(kù)
@Test
public void testCreatIndex(){
elasticsearchTemplate.createIndex(Book.class);
elasticsearchTemplate.putMapping(Book.class);
}
// 新增或者更新
@Test
public void save(){
Book book = new Book(20,"20","20",20L);
bookDao.save(book);
}
// 刪除
@Test
public void testDelete(){
bookDao.deleteById(20);
}
@Test
public void testFindById(){
Book book = bookDao.findById(20).get();
System.out.println(book);
}
@Test
public void testFindByPageAndSort() throws IOException {
// PageRequest.of() 構(gòu)建的是一個(gè)Pageable對(duì)象,此對(duì)象是在spring-data-commons包下
// 所以凡是spring data 系列,都可以用該對(duì)象來(lái)進(jìn)行分頁(yè)
Page<Book> books = bookDao.findAll(PageRequest.of(0, 10,Sort.Direction.ASC,"sales"));
// 總條數(shù)
long totalElements = books.getTotalElements();
// 總頁(yè)數(shù)
int totalPages = books.getTotalPages();
System.out.println(totalElements);
System.out.println(totalPages);
books.forEach(book -> System.out.println(book));
}方法命名規(guī)則查詢(xún)

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface BookDao extends ElasticsearchRepository<Book, Integer> {
List<Book> findByContent(String content);
List<Book> findByContentAndTitle(String content, String title);
Page<Book> findByContent(String content, Pageable pageable);
}
@Test
public void testMethodName(){
List<Book> byContentAndTitle = bookDao.findByContentAndTitle("程序", "程序");
byContentAndTitle.forEach(book -> System.out.println(book));
}springdata對(duì)es沒(méi)有封裝的方法
例如term、query_string、高亮顯示等,就用原生api
@Test
public void findQueryString(){
//沒(méi)有封裝 的方法
SearchQuery searchQuery=new NativeSearchQueryBuilder()
//依舊傳遞的查詢(xún)方式 查詢(xún)參數(shù)
.withQuery(QueryBuilders.queryStringQuery("我是程序員"))
.build();
Page<Book> page = bookDao.search(searchQuery);
long totalElements = page.getTotalElements();
System.out.println("總條數(shù):"+totalElements);
int totalPages = page.getTotalPages();
System.out.println("總頁(yè)數(shù):"+totalPages);
List<Book> books = page.getContent();
books.forEach(b-> System.out.println(b));
}
@Test
public void findTerm2(){
//沒(méi)有封裝 的方法
SearchQuery searchQuery=new NativeSearchQueryBuilder()
//依舊傳遞的查詢(xún)方式 查詢(xún)參數(shù)
.withQuery(QueryBuilders.termQuery("content","程序"))
.build();
Page<Book> page = bookDao.search(searchQuery);
long totalElements = page.getTotalElements();
System.out.println("總條數(shù):"+totalElements);
int totalPages = page.getTotalPages();
System.out.println("總頁(yè)數(shù):"+totalPages);
List<Book> books = page.getContent();
books.forEach(b-> System.out.println(b));
}高亮顯示
@Test
public void testHighLight() {
SearchQuery searchQuery = new NativeSearchQueryBuilder()
//依舊傳遞的查詢(xún)方式 查詢(xún)參數(shù)
.withQuery(QueryBuilders.termQuery("content", "程序"))
.withHighlightFields(new HighlightBuilder.Field("content").preTags("<xh style='color:red'>").postTags("</xh>"))
.build();
AggregatedPage<Book> page = elasticsearchTemplate.queryForPage(searchQuery, Book.class, new SearchResultMapper() {
//自定義結(jié)果映射器 核心 將高亮字段取出 設(shè)置對(duì)象 返回?cái)?shù)據(jù)就有高亮顯示 而spring-data-es 默認(rèn)實(shí)現(xiàn)
//DefaultResultMapper 它 不會(huì)取出高亮字段 不用
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
List<Book> books = new ArrayList<>();
// 總條數(shù)
long totalHits = searchResponse.getHits().getTotalHits();
//System.out.println(totalHits);
// 數(shù)據(jù),包含高亮顯示的字段
SearchHits hits = searchResponse.getHits();
Iterator<SearchHit> iterator = hits.iterator();
while (iterator.hasNext()) {
SearchHit sh = iterator.next();
// 每一條數(shù)據(jù){id=17, title=程序員的自我修養(yǎng)—鏈接、裝載與庫(kù), content=俯瞰程序前世今生參透代碼如何變成程序在系統(tǒng)中運(yùn)行 透過(guò)系統(tǒng)軟件底層形成機(jī)制走進(jìn)程序世界探索深層次的自己, sales=6856}
//高亮字段{content=[content], fragments[[俯瞰<xh style='color:red'>程序</xh>前世今生參透代碼如何變成<xh style='color:red'>程序</xh>在系統(tǒng)中運(yùn)行 透過(guò)系統(tǒng)軟件底層形成機(jī)制走進(jìn)<xh style='color:red'>程序</xh>世界探索深層次的自己]]}
Map<String, Object> source = sh.getSource();
System.out.println("每一條數(shù)據(jù)" + source);
Map<String, HighlightField> highlightFields = sh.getHighlightFields();
System.out.println("高亮字段" + highlightFields);
//開(kāi)始封裝book對(duì)象
Book book = new Book();
Integer id = (Integer) source.get("id");
book.setId(id);
String title = (String) source.get("title");
book.setTitle(title);
HighlightField content = highlightFields.get("content");
book.setContent(content.getFragments()[0].toString());
Integer sales = (Integer) source.get("sales");
book.setSales(Long.valueOf(sales));
books.add(book);
}
return new AggregatedPageImpl(books, pageable, totalHits);
}
});
long totalElements = page.getTotalElements();
System.out.println("總條數(shù):" + totalElements);
int totalPages = page.getTotalPages();
System.out.println("總頁(yè)數(shù):" + totalPages);
List<Book> books = page.getContent();
books.forEach(b -> System.out.println(b));
}elasticsearch transport 通過(guò)9300操作
maven
<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>
</dependencies>// 創(chuàng)建客戶(hù)端對(duì)象
private TransportClient client;
// 創(chuàng)建客戶(hù)端對(duì)象
@Before
public void init() {
try {
//創(chuàng)建一個(gè)客戶(hù)端對(duì)象
Settings settings = Settings.builder()
.put("cluster.name", "my-elasticsearch")
.build();
client = new PreBuiltTransportClient(settings)
//少服務(wù)器的地址
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
// .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9301))
// .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9302));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
// 創(chuàng)建type和mapping
client.admin().indices().preparePutMapping("test02")
.setType("book")
.setSource("{\n" +
" \"book\": {\n" +
" \"properties\": {\n" +
" \"id\": {\n" +
" \t\"type\": \"long\",\n" +
" \"store\": true,\n" +
" \"index\":\"not_analyzed\"\n" +
" },\n" +
" \"title\": {\n" +
" \t\"type\": \"text\",\n" +
" \"store\": true,\n" +
" \"index\":\"analyzed\",\n" +
" \"analyzer\":\"ik_max_word\"\n" +
" },\n" +
" \"content\": {\n" +
" \t\"type\": \"text\",\n" +
" \"store\": true,\n" +
" \"index\":\"analyzed\",\n" +
" \"analyzer\":\"ik_max_word\"\n" +
" },\n" +
" \"sales\":{\n" +
" \"type\": \"long\",\n" +
" \"store\": true,\n" +
" \"index\":\"not_analyzed\"\n" +
" }\n" +
" }\n" +
" }\n" +
" }", XContentType.JSON)
.get();
// 文檔的crud
@Test
public void testAdd(){
client.prepareIndex("test02", "book", "1")
.setSource(
"{\n" +
"\t\"id\":1,\n" +
"\t\"title\":\"測(cè)試添加\",\n" +
"\t\"content\":\"測(cè)試添加數(shù)據(jù)\",\n" +
"\t\"sales\":666\n" +
"}",XContentType.JSON
)
.get();
}
// 實(shí)體類(lèi)進(jìn)行存儲(chǔ)
@Test
public void testAdd() throws JsonProcessingException {
Book book = new Book();
book.setId(2L);
book.setTitle("對(duì)象測(cè)試");
book.setContent("對(duì)象測(cè)試內(nèi)容");
book.setSales(1000L);
// 使用json轉(zhuǎn)換工具
ObjectMapper mappers = new ObjectMapper();
String string = mappers.writeValueAsString(book);
client.prepareIndex("test02", "book", "2")
.setSource(
string,XContentType.JSON
)
.get();
}
@Test
public void deleteDocument(){
client.prepareDelete("test02", "book", "1").get();
}
// 批量導(dǎo)入
@Test
public void bulkAdd() throws IOException {
BulkRequestBuilder bulkRequest = client.prepareBulk();
// 數(shù)據(jù)在本地中,進(jìn)行讀取
File file = new File("F:\\darkHorse\\darkHorsePool\\springbootSeries\\dailyQuest\\day90_elasticSearch\\resource\\esData.txt");
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String line = null;
int i = 1000;
while ((line = bufferedReader.readLine()) != null){
bulkRequest.add(client.prepareIndex("test02", "book",i++ + "")
.setSource(line,XContentType.JSON)
);
}
BulkResponse bulkResponse = bulkRequest.get();
if (bulkResponse.hasFailures()) {
// process failures by iterating through each bulk response item
}
}
@Test
public void testFindIds(){
SearchRequestBuilder searchRequestBuilder = client.prepareSearch("test02")
.setTypes("book")
//這個(gè)地方 告訴構(gòu)建器 使用什么類(lèi)型查詢(xún)方式
//查詢(xún)方式 使用 QueryBuilders.term...matchall....queryString
.setQuery(QueryBuilders.idsQuery().addIds("1000","1002","1003"))
.setFrom(0)
.setSize(20);
//返回了一個(gè) SearchResponse 響應(yīng)對(duì)象
SearchResponse searchResponse = searchRequestBuilder.get();
SearchHits hits = searchResponse.getHits();
long totalHits = hits.getTotalHits();
System.out.println("一共多少條記錄:"+totalHits);
Iterator<SearchHit> iterator = hits.iterator();
while (iterator.hasNext()){
SearchHit searchHit = iterator.next();
Map<String, Object> source = searchHit.getSource();
System.out.println(source);
}
}
SearchRequestBuilder searchRequestBuilder = client.prepareSearch("test02")
.setTypes("book")
//這個(gè)地方 告訴構(gòu)建器 使用什么類(lèi)型查詢(xún)方式
//查詢(xún)方式 使用 QueryBuilders.term...matchall....queryString
.setQuery(QueryBuilders.termQuery("content","程序"))
.setFrom(0)
.setSize(20);
@Test
public void highLight() {
HighlightBuilder highlightBuilder = new HighlightBuilder()
.preTags("<font style='color:red'>")
.postTags("</font>")
.field("content");
SearchRequestBuilder searchRequestBuilder = client.prepareSearch("test02")
.setTypes("book")
//這個(gè)地方 告訴構(gòu)建器 使用什么類(lèi)型查詢(xún)方式
//查詢(xún)方式 使用 QueryBuilders.term...matchall....queryString
.setQuery(QueryBuilders.termQuery("content", "程序"))
.setFrom(0)
.setSize(20)
.highlighter(highlightBuilder);
//返回了一個(gè) SearchResponse 響應(yīng)對(duì)象
SearchResponse searchResponse = searchRequestBuilder.get();
SearchHits hits = searchResponse.getHits();
long totalHits = hits.getTotalHits();
System.out.println("一共多少條記錄:" + totalHits);
Iterator<SearchHit> iterator = hits.iterator();
while (iterator.hasNext()) {
SearchHit searchHit = iterator.next();
Map<String, Object> source = searchHit.getSource();
System.out.println(source);
//獲取高亮顯示的內(nèi)容 這是一個(gè)map集合
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
HighlightField content = highlightFields.get("content");
Text[] fragments = content.getFragments();
System.out.println(fragments[0].toString());
}
}以上就是Java實(shí)現(xiàn)調(diào)用ElasticSearch API的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Java調(diào)用ElasticSearch API的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java中構(gòu)造器內(nèi)部調(diào)用構(gòu)造器實(shí)例詳解
在本篇文章里小編給大家分享的是關(guān)于java中構(gòu)造器內(nèi)部調(diào)用構(gòu)造器實(shí)例內(nèi)容,需要的朋友們可以學(xué)習(xí)下。2020-05-05
Springboot分模塊項(xiàng)目搭建的實(shí)現(xiàn)
在軟件開(kāi)發(fā)中,利用Spring?Boot進(jìn)行分模塊項(xiàng)目搭建能夠提高代碼的模塊化和復(fù)用性,本文主要介紹了Springboot分模塊項(xiàng)目搭建的實(shí)現(xiàn),感興趣的可以了解一下2024-10-10
詳解Mybatis逆向工程中使用Mysql8.0版本驅(qū)動(dòng)遇到的問(wèn)題
今天在使用 8.0.12 版的 mysql 驅(qū)動(dòng)時(shí)遇到了各種各樣的坑。這篇文章主要介紹了詳解Mybatis逆向工程中使用Mysql8.0版本驅(qū)動(dòng)遇到的問(wèn)題,感興趣的小伙伴們可以參考一下2018-10-10
詳解在idea 中使用Mybatis Generator逆向工程生成代碼
這篇文章主要介紹了在idea 中使用Mybatis Generator逆向工程生成代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
一文搞懂MyBatis多數(shù)據(jù)源Starter實(shí)現(xiàn)
本文將實(shí)現(xiàn)一個(gè)MyBatis的Springboot的Starter包,引用這個(gè)Starter包后,僅需要提供少量配置信息,就能夠完成MyBatis多數(shù)據(jù)源的初始化和使用,需要的小伙伴可以參考一下2023-04-04
Mybatis批量更新數(shù)據(jù)庫(kù)錯(cuò)誤問(wèn)題
這篇文章主要介紹了Mybatis批量更新數(shù)據(jù)庫(kù)錯(cuò)誤問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08

