ElasticSearch简单入门(二)
程序员文章站
2022-07-05 08:04:18
...
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);
}
}