ElasticSearch搜尋引擎在JAVA中的簡單使用
Elasticsearch常用操作和核心原理見文章:https://blog.csdn.net/sdksdk0/article/details/78469190
本文參照:https://www.2cto.com/kf/201802/719374.html
一、引入ElasticSearch的jar
org.elasticsearch
elasticsearch
2.4.0
junit
junit
4.12
com.fasterxml.jackson.core
jackson-core
2.8.1
com.fasterxml.jackson.core
jackson-databind
2.8.1
com.fasterxml.jackson.core
jackson-annotations
2.8.1
二、建立文件型別實體Bean
package cn.elasticsearch.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; } @Override public String toString() { return "Article [id=" + id + ", title=" + title + ", content=" + content + "]"; }
}
三、ElasticSearch中建立文件,自動建立索引
// 直接在ElasticSearch中建立文件,自動建立索引
@Test
public void demo1() throws IOException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 建立物件要新增物件的JSON格式字串 XContentBuilder builder = XContentFactory.jsonBuilder().startObject() .field("1", 1) .field("title", "ElasticSearch是一個基於Lucene的搜尋伺服器") .field("content", "它提供了一個分散式多使用者能力的全文搜尋引擎,基於RESTful web介面。Elasticsearch是用Java開發的,並作為Apache許可條款下的開放原始碼釋出,是當前流行的企業級搜尋引擎。設計用於雲端計算中,能夠達到實時搜尋,穩定,可靠,快速,安裝使用方便。") .endObject(); // 建立文件物件 client.prepareIndex("blog1", "article", "1").setSource(builder).get(); // 關閉連線 client.close(); }
四、QueryBuilders.matchAllQuery() 查詢所有
// 搜尋在ElasticSearch中建立的文件物件,使用QueryBuilders.matchAllQuery()查詢所有
@Test
public void demo2() throws UnknownHostException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 手冊資料
SearchResponse searchResponse = client
.prepareSearch("blog1")
.setTypes("article")
.setQuery(QueryBuilders.matchAllQuery()).get();
printSearchResponse(searchResponse);
// 關閉連線
client.close();
}
五、QueryBuilders.queryStringQuery() 分詞內容查詢
// 使用QueryBuilders.queryStringQuery(搜尋內容)進行分詞內容查詢
@Test
public void demo3() throws UnknownHostException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 搜尋資料
SearchResponse searchResponse = client
.prepareSearch("blog1")
.setTypes("article")
.setQuery(QueryBuilders.queryStringQuery("全文")).get();
printSearchResponse(searchResponse);
// 關閉連線
client.close();
}
六、QueryBuilders.wildcardQuery() 範圍分詞模糊查詢
// 使用QueryBuilders.wildcardQuery(“搜尋範圍:如title|content”,”查詢內容”)進行範圍分詞模糊查詢
// *表示任意字串 ?表示任意字元
// 查詢結果為0條,說明沒有詞條包含”全文”
@Test
public void demo4() throws UnknownHostException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 搜尋資料
SearchResponse searchResponse = client
.prepareSearch("blog1")
.setTypes("article")
.setQuery(QueryBuilders.wildcardQuery("content", "*全文*")).get();
printSearchResponse(searchResponse);
// 關閉連線
client.close();
}
七、QueryBuilders.termQuery() 範圍詞條查詢
// 使用QueryBuilders.termQuery(“搜尋範圍:如title|content”,”查詢內容”)進行範圍詞條查詢
// 查詢結果為0條,說明沒有”搜尋”這個詞條
@Test
public void demo5() throws UnknownHostException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 搜尋資料
SearchResponse searchResponse = client
.prepareSearch("blog2")
.setTypes("article")
.setQuery(QueryBuilders.termQuery("content", "搜")).get();
printSearchResponse(searchResponse);
// 關閉連線
client.close();
八、建立/刪除索引
// 索引操作 — 建立與刪除
@Test
public void demo6() throws UnknownHostException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 建立索引
client.admin().indices().prepareCreate("blog2").get();
// 刪除索引
//client.admin().indices().prepareDelete("blog2").get();
// 關閉連線
client.close();
}
九、建立對映
// 對映操作 — 建立
@Test
public void demo7() throws IOException, ExecutionException, InterruptedException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 新增對映
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").endObject()
.startObject("content").field("type", "string").field("store", "yes").field("analyzer", "ik").endObject()
.endObject()
.endObject()
.endObject();
PutMappingRequest mapping = Requests.putMappingRequest("blog2")
.type("article").source(builder);
client.admin().indices().putMapping(mapping).get();
// 關閉連線
client.close();
}
十、建立文件
// 文件操作 — 建立
@Test
public void demo8() throws IOException, ExecutionException, InterruptedException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 建立jackson解析物件
ObjectMapper objectMapper = new ObjectMapper();
for (int i = 1;i <= 100;i++){
// 描述json 資料
/*
* {id:xxx, title:xxx, content:xxx}
*/
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();
}
// 關閉連線
client.close();
}
十一、分頁搜尋
// 分頁搜尋
@Test
public void demo11() throws UnknownHostException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 搜尋資料
SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog2")
.setTypes("article")
.setQuery(QueryBuilders.matchAllQuery());
// 通過SearchRequestBuilder的setFrom和setSize方法實現分頁
// 顯示第二頁的資料,每頁顯示20條
searchRequestBuilder.setFrom(2);
searchRequestBuilder.setSize(20);
SearchResponse searchResponse = searchRequestBuilder.get();
printSearchResponse(searchResponse);
// 關閉連線
client.close();
}
十二、高亮顯示
// 高亮顯示
@Test
public void demo12() throws IOException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
ObjectMapper objectMapper = new ObjectMapper();
// 搜尋資料
SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog2")
.setTypes("article")
.setQuery(QueryBuilders.termQuery("title","搜尋"));
// 高亮應用的內容
searchRequestBuilder.addHighlightedField("title"); // 對title欄位進行高亮
searchRequestBuilder.setHighlighterPreTags("<em>"); // 前置元素
searchRequestBuilder.setHighlighterPostTags("</em>"); // 後置元素
// 通過SearchRequestBuilder的setFrom和setSize方法實現分頁
// 顯示第二頁的資料,每頁顯示20條
searchRequestBuilder.setFrom(2).setSize(20);
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(); //每個查詢物件
// 將高亮處理後的內容,替換原有高亮內容(原有內容,可能會出現顯示不全)
Map<string,highlightfield> highlightFields = searchHit.getHighlightFields();
HighlightField titleField = highlightFields.get("title");
// 獲取到原有內容中的每個高亮顯示的集中的位置,fragment就是高亮片段
Text[] fragments = titleField.fragments();
String title = "";
for (Text text : fragments){
title += text;
}
// 通過ObjectMapper的readVallue將查詢結果轉換成Article物件
Article article = objectMapper.readValue(searchHit.getSourceAsString(), Article.class);
// 用高亮後內容,替換原有內容
article.setTitle(title);
System.out.println(article);
}
// 關閉連線
client.close();
}
十三、文件修改
// 文件操作 — 修改
@Test
public void demo9() throws IOException, ExecutionException, InterruptedException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 描述json 資料
/*
* {id:xxx, title:xxx, content:xxx}
*/
Article article = new Article();
article.setId(2);
article.setTitle("搜尋工作其實也不難");
article.setContent("我們希望我們的搜尋解決方案要快,我們希望有一個零配置和一個完全免費的搜尋模式,我們希望能夠簡單地使用JSON通過HTTP的索引資料,我們希望我們的搜尋伺服器始終可用,我們希望能夠一臺開始並擴充套件到數百,我們要實時搜尋,我們要簡單的多租戶,我們希望建立一個雲的解決方案。Elasticsearch旨在解決所有這些問題和更多的問題。");
// 建立jackson解析物件
ObjectMapper objectMapper = new ObjectMapper();
// 修改文件 --- 方式一
//client.prepareUpdate("blog2", "article", article.getId().toString())
// .setDoc(objectMapper.writeValueAsString(article)).get();
// 修改文件 --- 方式二
client.update(
new UpdateRequest("blog2", "article", article.getId().toString())
.doc(objectMapper.writeValueAsString(article))
).get();
// 關閉連線
client.close();
}
十四、文件刪除
// 文件操作 — 刪除
@Test
public void demo10() throws IOException, ExecutionException, InterruptedException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
Article article = new Article();
article.setId(2);
// 刪除文件 --- 方式一
//client.prepareDelete("blog2", "article", article.getId().toString()).get();
// 刪除文件 --- 方式二
client.delete(
new DeleteRequest("blog2", "article", article.getId().toString())
).get();
// 關閉連線
client.close();
}
完整程式碼:
package cn.elasticsearch.test;
import cn.elasticsearch.domain.Article;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.highlight.HighlightField;
import org.junit.Test;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutionException;
// ElasticSearch 測試程式
public class ElasticSearchTest {
// 直接在ElasticSearch中建立文件,自動建立索引
@Test
public void demo1() throws IOException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 建立物件要新增物件的JSON格式字串
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
.field("1", 1)
.field("title", "ElasticSearch是一個基於Lucene的搜尋伺服器")
.field("content", "它提供了一個分散式多使用者能力的全文搜尋引擎,基於RESTful web介面。Elasticsearch是用Java開發的,並作為Apache許可條款下的開放原始碼釋出,是當前流行的企業級搜尋引擎。設計用於雲端計算中,能夠達到實時搜尋,穩定,可靠,快速,安裝使用方便。")
.endObject();
// 建立文件物件
client.prepareIndex("blog1", "article", "1").setSource(builder).get();
// 關閉連線
client.close();
}
// 搜尋在ElasticSearch中建立的文件物件,使用QueryBuilders.matchAllQuery()查詢所有
@Test
public void demo2() throws UnknownHostException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 手冊資料
SearchResponse searchResponse = client
.prepareSearch("blog1")
.setTypes("article")
.setQuery(QueryBuilders.matchAllQuery()).get();
printSearchResponse(searchResponse);
// 關閉連線
client.close();
}
// 使用QueryBuilders.queryStringQuery(搜尋內容)進行分詞內容查詢
@Test
public void demo3() throws UnknownHostException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 搜尋資料
SearchResponse searchResponse = client
.prepareSearch("blog1")
.setTypes("article")
.setQuery(QueryBuilders.queryStringQuery("全文")).get();
printSearchResponse(searchResponse);
// 關閉連線
client.close();
}
// 使用QueryBuilders.wildcardQuery("搜尋範圍:如title|content","查詢內容")進行範圍分詞模糊查詢
// *表示任意字串 ?表示任意字元
// 查詢結果為0條,說明沒有詞條包含"全文"
@Test
public void demo4() throws UnknownHostException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 搜尋資料
SearchResponse searchResponse = client
.prepareSearch("blog1")
.setTypes("article")
.setQuery(QueryBuilders.wildcardQuery("content", "*全文*")).get();
printSearchResponse(searchResponse);
// 關閉連線
client.close();
}
// 使用QueryBuilders.termQuery("搜尋範圍:如title|content","查詢內容")進行範圍詞條查詢
// 查詢結果為0條,說明沒有"搜尋"這個詞條
@Test
public void demo5() throws UnknownHostException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 搜尋資料
SearchResponse searchResponse = client
.prepareSearch("blog2")
.setTypes("article")
.setQuery(QueryBuilders.termQuery("content", "搜")).get();
printSearchResponse(searchResponse);
// 關閉連線
client.close();
}
// 索引操作 --- 建立與刪除
@Test
public void demo6() throws UnknownHostException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 建立索引
client.admin().indices().prepareCreate("blog2").get();
// 刪除索引
//client.admin().indices().prepareDelete("blog2").get();
// 關閉連線
client.close();
}
// 對映操作 --- 建立
@Test
public void demo7() throws IOException, ExecutionException, InterruptedException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 新增對映
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").endObject()
.startObject("content").field("type", "string").field("store", "yes").field("analyzer", "ik").endObject()
.endObject()
.endObject()
.endObject();
PutMappingRequest mapping = Requests.putMappingRequest("blog2")
.type("article").source(builder);
client.admin().indices().putMapping(mapping).get();
// 關閉連線
client.close();
}
// 文件操作 --- 建立
@Test
public void demo8() throws IOException, ExecutionException, InterruptedException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 建立jackson解析物件
ObjectMapper objectMapper = new ObjectMapper();
for (int i = 1;i <= 100;i++){
// 描述json 資料
/*
* {id:xxx, title:xxx, content:xxx}
*/
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();
}
// 關閉連線
client.close();
}
// 分頁搜尋
@Test
public void demo11() throws UnknownHostException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 搜尋資料
SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog2")
.setTypes("article")
.setQuery(QueryBuilders.matchAllQuery());
// 通過SearchRequestBuilder的setFrom和setSize方法實現分頁
// 顯示第二頁的資料,每頁顯示20條
searchRequestBuilder.setFrom(2);
searchRequestBuilder.setSize(20);
SearchResponse searchResponse = searchRequestBuilder.get();
printSearchResponse(searchResponse);
// 關閉連線
client.close();
}
// 高亮顯示
@Test
public void demo12() throws IOException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
ObjectMapper objectMapper = new ObjectMapper();
// 搜尋資料
SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog2")
.setTypes("article")
.setQuery(QueryBuilders.termQuery("title","搜尋"));
// 高亮應用的內容
searchRequestBuilder.addHighlightedField("title"); // 對title欄位進行高亮
searchRequestBuilder.setHighlighterPreTags("<em>"); // 前置元素
searchRequestBuilder.setHighlighterPostTags("</em>"); // 後置元素
// 通過SearchRequestBuilder的setFrom和setSize方法實現分頁
// 顯示第二頁的資料,每頁顯示20條
searchRequestBuilder.setFrom(2).setSize(20);
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(); //每個查詢物件
// 將高亮處理後的內容,替換原有高亮內容(原有內容,可能會出現顯示不全)
Map<string,highlightfield> highlightFields = searchHit.getHighlightFields();
HighlightField titleField = highlightFields.get("title");
// 獲取到原有內容中的每個高亮顯示的集中的位置,fragment就是高亮片段
Text[] fragments = titleField.fragments();
String title = "";
for (Text text : fragments){
title += text;
}
// 通過ObjectMapper的readVallue將查詢結果轉換成Article物件
Article article = objectMapper.readValue(searchHit.getSourceAsString(), Article.class);
// 用高亮後內容,替換原有內容
article.setTitle(title);
System.out.println(article);
}
// 關閉連線
client.close();
}
// 文件操作 --- 修改
@Test
public void demo9() throws IOException, ExecutionException, InterruptedException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
// 描述json 資料
/*
* {id:xxx, title:xxx, content:xxx}
*/
Article article = new Article();
article.setId(2);
article.setTitle("搜尋工作其實也不難");
article.setContent("我們希望我們的搜尋解決方案要快,我們希望有一個零配置和一個完全免費的搜尋模式,我們希望能夠簡單地使用JSON通過HTTP的索引資料,我們希望我們的搜尋伺服器始終可用,我們希望能夠一臺開始並擴充套件到數百,我們要實時搜尋,我們要簡單的多租戶,我們希望建立一個雲的解決方案。Elasticsearch旨在解決所有這些問題和更多的問題。");
// 建立jackson解析物件
ObjectMapper objectMapper = new ObjectMapper();
// 修改文件 --- 方式一
//client.prepareUpdate("blog2", "article", article.getId().toString())
// .setDoc(objectMapper.writeValueAsString(article)).get();
// 修改文件 --- 方式二
client.update(
new UpdateRequest("blog2", "article", article.getId().toString())
.doc(objectMapper.writeValueAsString(article))
).get();
// 關閉連線
client.close();
}
// 文件操作 --- 刪除
@Test
public void demo10() throws IOException, ExecutionException, InterruptedException {
// 建立ElasticSearch連線物件
Client client = getElasticSearchClient();
Article article = new Article();
article.setId(2);
// 刪除文件 --- 方式一
//client.prepareDelete("blog2", "article", article.getId().toString()).get();
// 刪除文件 --- 方式二
client.delete(
new DeleteRequest("blog2", "article", article.getId().toString())
).get();
// 關閉連線
client.close();
}
// 遍歷列印查詢後的結果
private void printSearchResponse(SearchResponse searchResponse) {
// 獲取命中次數,查詢結果又多少物件
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"));
}
}
// 獲取ElasticSearcch Client物件
private Client getElasticSearchClient() throws UnknownHostException {
return TransportClient
.builder()
.build()
.addTransportAddress(
new InetSocketTransportAddress(
InetAddress.getByName("127.0.0.1"), 9300));
}
}