ElasticSearch簡單入門(二)
阿新 • • 發佈:2021-01-04
技術標籤:ElasticSearchelasticsearchjava
IK分詞器
前提: 預設ES中採用標準分詞器進行分詞,但這種方式並不適用於中文網站,因此需要修改ES對中文友好分詞,從而達到更佳的搜尋的效果,IK分詞器就是一個較好的選擇
本地安裝IK
1、下載對應版本,一般IK分詞器的版本與ElasticSearch的版本相對應
2、在glugins目錄下建立個目錄(名字隨意),將IK的zip包放到該目錄下,然後進行解壓
- unzip elasticsearch-analysis-ik-6.8.0.zip
3、重啟ES生效,會自動掃描glugins下的外掛
測試
PUT /ems { "mappings":{ "emp":{ "properties":{ "name":{ "type":"text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" }, "age":{ "type":"integer" }, "bir":{ "type":"date" }, "content":{ "type":"text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" }, "address":{ "type":"keyword" } } } } } PUT /ems/emp/_bulk {"index":{}} {"name":"張學友","age":23,"bir":"2012-12-12","content":"為開發團隊選擇一款優秀的MVC框架是件難事兒,在眾多可行的方案中決擇需要很高的經驗和水平","address":"北京"} {"index":{}} {"name":"劉德華","age":24,"bir":"2012-12-12","content":"Spring 框架是一個分層架構,由 7 個定義良好的模組組成。Spring 模組構建在核心容器之上,核心容器定義了建立、配置和管理 bean 的方式","address":"上海"} {"index":{}} {"name":"張學友的表弟","age":8,"bir":"2012-12-12","content":"Spring Cloud 作為Java 語言的微服務框架,它依賴於Spring Boot,有快速開發、持續交付和容易部署等特點。Spring Cloud 的元件非常多,涉及微服務的方方面面,井在開源社群Spring 和Netflix 、Pivotal 兩大公司的推動下越來越完善","address":"無錫"} {"index":{}} {"name":"郭富城","age":9,"bir":"2012-12-12","content":"Spring的目標是致力於全方位的簡化Java開發。 這勢必引出更多的解釋, Spring是如何簡化Java開發的?","address":"南京"} {"index":{}} {"name":"黎明","age":43,"bir":"2012-12-12","content":"Redis是一個開源的使用ANSI C語言編寫、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API","address":"杭州"} {"index":{}} {"name":"劉德華的表哥","age":59,"bir":"2012-12-12","content":"ElasticSearch是一個基於Lucene的搜尋伺服器。它提供了一個分散式多使用者能力的全文搜尋引擎,基於RESTful web介面","address":"北京"} GET /ems/emp/_search { "query":{ "term":{ "content":"框架" } } }
Java操作ES
引入依賴
<dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>6.8.0</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>6.8.0</version> </dependency> <dependency> <groupId>org.elasticsearch.plugin</groupId> <artifactId>transport-netty4-client</artifactId> <version>6.8.0</version> </dependency>
1、建立客戶端操作物件
//返回操作ES的TransportClient
public PreBuiltTransportClient client() throws UnknownHostException {
PreBuiltTransportClient client = new PreBuiltTransportClient(Settings.EMPTY);
client.addTransportAddress(new TransportAddress(InetAddress.getByName("192.168.1.21"), 9300));
return client;
}
2、建立索引
//建立索引
@org.junit.Test
public void test01() throws UnknownHostException, ExecutionException, InterruptedException {
PreBuiltTransportClient client = client();
//定義索引請求
CreateIndexRequest ems = new CreateIndexRequest("dangdang");
//執行建立索引的請求
CreateIndexResponse createIndexResponse = client.admin().indices().create(ems).get();
System.out.println(createIndexResponse.isAcknowledged());
}
3、刪除索引
//刪除索引
@org.junit.Test
public void test02() throws UnknownHostException, ExecutionException, InterruptedException {
PreBuiltTransportClient client = client();
//定義刪除索引的請求
DeleteIndexRequest ems = new DeleteIndexRequest("ems");
AcknowledgedResponse acknowledgedResponse = client.admin().indices().delete(ems).get();
System.out.println(acknowledgedResponse.isAcknowledged());
}
4、建立索引和型別
@org.junit.Test
public void test03() throws UnknownHostException, ExecutionException, InterruptedException {
PreBuiltTransportClient client = client();
//建立索引
CreateIndexRequest ems = new CreateIndexRequest("ems");
//定義json格式對映
String json = "{\"properties\":{\"name\":{\"type\":\"text\",\"analyzer\":\"ik_max_word\"}," +
"\"age\":{\"type\":\"integer\"},\"sex\":{\"type\":\"keyword\"}," +
"\"content\":{\"type\":\"text\",\"analyzer\":\"ik_max_word\"}}}";
//設定型別和對映
ems.mapping("emp", json, XContentType.JSON);
//執行
CreateIndexResponse createIndexResponse = client.admin().indices().create(ems).get();
System.out.println(createIndexResponse.isAcknowledged());
}
5、根據指定索引和型別下建立文件(指定ID)
@org.junit.Test
public void test04() throws UnknownHostException {
PreBuiltTransportClient client = client();
Emp emp = new Emp("張學友", 50, "男", "我是一個歌神");
String s = JSONObject.toJSONString(emp);
IndexResponse indexResponse = client.prepareIndex("ems", "emp", "1").setSource(s, XContentType.JSON).get();
System.out.println(indexResponse.status());
}
6、根據指定索引和型別下建立文件(自動生成ID)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {
private String name;
private int age;
private String sex;
private String content;
}
@org.junit.Test
public void test05() throws UnknownHostException {
PreBuiltTransportClient client = client();
Emp emp = new Emp("劉德華", 100, "男", "我是一個影帝");
String s = JSONObject.toJSONString(emp);
IndexResponse indexResponse = client.prepareIndex("ems", "emp").setSource(s, XContentType.JSON).get();
System.out.println(indexResponse.status());
}
7、更新一條索引
@org.junit.Test
public void test06() throws UnknownHostException {
PreBuiltTransportClient client = client();
Emp emp = new Emp();
emp.setName("我是更新後的張學友");
String s = JSONObject.toJSONString(emp);
UpdateResponse updateResponse = client.prepareUpdate("ems", "emp", "1").setDoc(s, XContentType.JSON).get();
System.out.println(updateResponse.status());
}
8、刪除一條索引
@org.junit.Test
public void test07() throws UnknownHostException {
PreBuiltTransportClient client = client();
DeleteResponse deleteResponse = client.prepareDelete("ems", "emp", "C5OPgHYBuGfbHGEA7OWh").get();
System.out.println(deleteResponse.status());
}
查詢操作
1、查詢所有並排序
@org.junit.Test
public void test09() throws UnknownHostException {
PreBuiltTransportClient client = client();
SearchResponse searchResponse = client.prepareSearch("ems")
.setTypes("emp")
.setQuery(QueryBuilders.matchAllQuery())
.addSort("age", SortOrder.ASC)
.get();
SearchHits hits = searchResponse.getHits();
System.out.println("符合的條數: " + hits.totalHits);
for (SearchHit hit : hits
) {
System.out.println("當前的索引分數:" + hit.getScore());
System.out.println("對應的結果:" + hit.getSourceAsString());
}
}
2、分頁查詢
@org.junit.Test
public void test10() throws UnknownHostException {
PreBuiltTransportClient client = client();
SearchResponse searchResponse = client.prepareSearch("ems")
.setTypes("emp")
.setQuery(QueryBuilders.matchAllQuery())
.setFrom(0)
.setSize(3)
.get();
SearchHits hits = searchResponse.getHits();
for (SearchHit hit : hits
) {
System.out.println("對應的結果:" + hit.getSourceAsString());
}
}
3、返回指定的欄位
@org.junit.Test
public void test11() throws UnknownHostException {
PreBuiltTransportClient client = client();
SearchResponse searchResponse = client.prepareSearch("ems")
.setTypes("emp")
.setQuery(QueryBuilders.matchAllQuery())
.setFetchSource("*", "age") //將age欄位排除在外
.get();
SearchHits hits = searchResponse.getHits();
for (SearchHit hit : hits
) {
System.out.println("對應的結果:" + hit.getSourceAsString());
}
}
4、term查詢
@org.junit.Test
public void test12() throws UnknownHostException {
PreBuiltTransportClient client = client();
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "張學友");
SearchResponse searchResponse = client.prepareSearch("ems")
.setTypes("emp")
.setQuery(termQueryBuilder)
.get();
System.out.println(searchResponse.getHits().getTotalHits());
}
5、範圍(range)查詢
@org.junit.Test
public void test13() throws UnknownHostException {
PreBuiltTransportClient client = client();
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").lt(22).gte(0);
SearchResponse searchResponse = client.prepareSearch("ems")
.setTypes("emp")
.setQuery(rangeQueryBuilder)
.get();
System.out.println(searchResponse.getHits().getTotalHits());
}
6、prefix 查詢
@org.junit.Test
public void test14() throws UnknownHostException {
PreBuiltTransportClient client = client();
PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery("name", "張");
SearchResponse searchResponse = client.prepareSearch("ems")
.setTypes("emp")
.setQuery(prefixQueryBuilder)
.get();
System.out.println(searchResponse.getHits().getTotalHits());
}
7、wildcard (萬用字元)查詢
@org.junit.Test
public void test15() throws UnknownHostException {
PreBuiltTransportClient client = client();
WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("name", "張*");
SearchResponse searchResponse = client.prepareSearch("ems")
.setTypes("emp")
.setQuery(wildcardQueryBuilder)
.get();
System.out.println(searchResponse.getHits().getTotalHits());
}
8、Ids 查詢
@org.junit.Test
public void test16() throws UnknownHostException {
PreBuiltTransportClient client = client();
IdsQueryBuilder idsQueryBuilder = QueryBuilders.idsQuery().addIds("1", "2");
SearchResponse searchResponse = client.prepareSearch("ems")
.setTypes("emp")
.setQuery(idsQueryBuilder)
.get();
System.out.println(searchResponse.getHits().getTotalHits());
}
9、fuzzy 模糊查詢
@org.junit.Test
public void test17() throws UnknownHostException {
PreBuiltTransportClient client = client();
FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("name", "張雪友");
SearchResponse searchResponse = client.prepareSearch("ems")
.setTypes("emp")
.setQuery(fuzzyQueryBuilder)
.get();
System.out.println(searchResponse.getHits().getTotalHits());
}
10、bool 查詢
@org.junit.Test
public void test18() throws UnknownHostException {
PreBuiltTransportClient client = client();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.should(QueryBuilders.matchAllQuery());
boolQueryBuilder.mustNot(QueryBuilders.rangeQuery("age").lte(8));
SearchResponse searchResponse = client.prepareSearch("ems")
.setTypes("emp")
.setQuery(boolQueryBuilder)
.get();
System.out.println(searchResponse.getHits().getTotalHits());
}
SpringBoot操作ES
引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
在SpringBoot中有兩種方式(兩個物件)來操作ES,一個是 RestHighLevelClient物件,一個是ElasticsearchRepository介面
RestHighLevelClient操作ES(適合進行復雜操作)
1、建立該物件的Bean,使用JavaConfig形式注入容器
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
//這個client用來替換transportClient(9300)物件
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
//定義客戶端配置物件 RestClient物件,埠號9200
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("192.168.1.21:9200")
.build();
return RestClients.create(clientConfiguration).rest();
}
}
2、刪除指定ID
//第一種用法
@Autowired
private RestHighLevelClient restHighLevelClient; //複雜查詢使用 比如:高亮查詢 指定條件查詢
@Test
public void test01() throws IOException {
DeleteRequest deleteRequest = new DeleteRequest("ems", "emp", "1");
DeleteResponse response = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(response.status());
}
3、建立指定文件
@Test
public void test02() throws IOException {
IndexRequest indexRequest = new IndexRequest("ems", "emp", "3");
indexRequest.source("{\"name\":\"小黑\",\"age\":\"66\"}", XContentType.JSON);
IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(response.status());
}
4、查詢所有
@Test
public void test03() throws IOException {
SearchRequest request = new SearchRequest("ems");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
request.types("emp").source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
for (SearchHit hit:hits
) {
System.out.println(hit.getSourceAsString());
}
// System.out.println(response.getHits().getTotalHits());
}
5、修改文件
@Test
public void test04() throws IOException {
UpdateRequest updateRequest = new UpdateRequest("ems", "emp", "3");
updateRequest.doc("{\"name\":\"修改後的小黑\",\"age\":88}",XContentType.JSON);
UpdateResponse response = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(response.status());
}
6、多條操作進行
@Test
public void test05() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
//新增
IndexRequest indexRequest = new IndexRequest("ems", "emp", "4");
indexRequest.source("{\"name\":\"小白\",\"age\":\"167\"}", XContentType.JSON);
//刪除
//修改
bulkRequest.add(indexRequest);
BulkResponse responses = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
BulkItemResponse[] items = responses.getItems();
for (BulkItemResponse item:items
) {
System.out.println(item.status());
}
}
7、複雜查詢-----分頁查詢並排序
@Test
public void test07() throws IOException {
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//設定查詢的條件
searchSourceBuilder.from(0).size(2).sort("age", SortOrder.DESC).query(QueryBuilders.matchAllQuery());
//設定查詢的索引和型別
searchRequest.indices("ems")
.types("emp")
.source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
for (SearchHit hit:hits
) {
System.out.println(hit.getSourceAsString());
}
}
8、複雜查詢-----高亮查詢
@Test
public void test08() throws IOException {
SearchRequest request = new SearchRequest();
SearchSourceBuilder builder = new SearchSourceBuilder();
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("content")
.requireFieldMatch(false)
.preTags("<span style='color:red;'>")
.postTags("</span>");
builder.from(0).size(2)
.sort("age",SortOrder.DESC)
.highlighter(highlightBuilder)
.query(QueryBuilders.termQuery("content","我是"));
request.indices("ems").types("emp").source(builder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
for (SearchHit hit:hits
) {
System.out.println(hit.getSourceAsString());
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
highlightFields.forEach((k,v) -> System.out.println("key:"+k+"value:"+v.fragments()[0]));
}
}
ElasticsearchRepository介面方式操作(適合簡單操作)
1、建立Entity
@Document(indexName = "dangdang",type = "book")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
@Id
private String id;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String name;
@Field(type = FieldType.Date)
private Date createDate;
@Field(type = FieldType.Keyword)
private String author;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String content;
}
2、編寫BookRepository
public interface BookRepository extends ElasticsearchRepository<Book,String> {
}
3、新增文件
@Autowired
private BookRepository bookRepository; //使用該物件進行CRUD的相關操作
//新增索引和更新索引id 存在更新 不存在則新增
@Test
public void test01(){
Book book = new Book();
book.setId("21");
book.setName("小顏");
book.setCreateDate(new Date());
book.setAuthor("吳亦凡");
book.setContent("這是我的一本新書");
Book book2 = new Book();
book2.setId("100");
book2.setName("小閆");
book2.setCreateDate(new Date());
book2.setAuthor("樸宰範");
book2.setContent("這是我的燙嘴rap");
bookRepository.save(book);
bookRepository.save(book2);
}
4、刪除一條記錄
@Test
public void test02(){
Book book = new Book();
book.setId("21");
bookRepository.delete(book);
}
5、查詢所有
@Test
public void test03(){
Iterable<Book> all = bookRepository.findAll();
for (Book book: all
) {
System.out.println(book);
}
}
6、查詢指定ID
@Test
public void test04(){
Optional<Book> book = bookRepository.findById("21");
System.out.println(book.get());
}
7、排序查詢
@Test
public void test05(){
Iterable<Book> books = bookRepository.findAll(Sort.by(Sort.Order.desc("createDate")));
for (Book book:books
) {
System.out.println(book);
}
}