Day122.ElasticSearch:高级客户端、SpringData Elasticsearch

目录

一、高级客户端 (JAVA API 操作ES ) ★

1、准备工作

2、索引操作

3、文档操作

4、DSL操作

二、SpringData Elasticsearch

1、测试

2、自定义方法 ★


一、高级客户端 (JAVA API 操作ES ) ★

官方文档:Getting started | Java REST Client [7.8] | Elastic

1、准备工作

1. 新建elasticsearch_demo Maven工程

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.6.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--elasticsearch的高级别rest客户端-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.8.0</version>
        </dependency>
        <!--elasticsearch的rest客户端-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>7.8.0</version>
        </dependency>
        <!--elasticsearch的核心jar包-->
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.8.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!--json转换的jar包-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.9</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
elasticsearch.host=localhost
elasticsearch.port=9200

3. 创建主目录,启动类

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

4. 创建配置类

@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
public class ElasticSearchConfig {

    private String host;
    private Integer port;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient restHighLevelClient =
                new RestHighLevelClient(RestClient.builder(new HttpHost(host,port,"http")));
        return restHighLevelClient;
    }
}

5. 创建测试实体

​
1. 准备实体

@Data
public class Student implements Serializable {
    private String name;
    private Integer age;
    private String remark;

}


​

6. 创建测试类

@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticSearchTest {

    @Autowired
    RestHighLevelClient client;

    @Test
    public void testResthightLevelClient() throws Exception {
        System.out.println("restHighLevelClient = " + client);
    }
}

2、索引操作

//创建索引
    @Test
    public void createIndex(){
        //指定索引名,注意导包:高级客户端
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("person");
        try {
            //设置
            createIndexRequest.mapping("{\n" +
                    "    \"properties\": {\n" +
                    "      \"name\": {\n" +
                    "        \"type\": \"keyword\",\n" +
                    "        \"index\": true,\n" +
                    "        \"store\": true\n" +
                    "      },\n" +
                    "      \"age\": {\n" +
                    "        \"type\": \"integer\",\n" +
                    "        \"index\": true,\n" +
                    "        \"store\": true\n" +
                    "      },\n" +
                    "      \"remark\": {\n" +
                    "        \"type\": \"text\",\n" +
                    "        \"index\": true,\n" +
                    "        \"store\": true,\n" +
                    "        \"analyzer\": \"ik_max_word\",\n" +
                    "        \"search_analyzer\": \"ik_smart\"\n" +
                    "      }\n" +
                    "    }\n" +
                    "  }", XContentType.JSON);
            CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            System.out.println(createIndexResponse.isAcknowledged());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //查看索引
    @Test
    public void getIndex(){
        GetIndexRequest request = new GetIndexRequest("person");
        try {
            GetIndexResponse getIndexResponse = restHighLevelClient.indices().get(request, RequestOptions.DEFAULT);
            System.out.println(getIndexResponse.getMappings());
            System.out.println(getIndexResponse.getSettings());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //删除索引
    @Test
    public void deleteIndex(){
        DeleteIndexRequest request = new DeleteIndexRequest("person");
        AcknowledgedResponse acknowledgedResponse = null;
        try {
            acknowledgedResponse = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(acknowledgedResponse.isAcknowledged());
    }

3、文档操作

@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticSearchDocTest {
    
    @Autowired
    RestHighLevelClient restHighLevelClient;

    @Test
    public void testResthightLevelClient() throws Exception {
        System.out.println("restHighLevelClient = " + restHighLevelClient);
    }

    //1.创建文档
    @Test
    public void createDoc(){
        //创建请求对象,索引不存在,会自动创建
        IndexRequest request = new IndexRequest("student");
        request.id("1");

        Student student = new Student();
        student.setAge(18);
        student.setName("robin");
        student.setRemark("good man");

        request.source(JSONObject.toJSONString(student), XContentType.JSON);

        IndexResponse indexResponse = null;
        try {
            indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(indexResponse.getResult());//CREATED
    }

    //2.修改文档
    @Test
    public void updateDoc(){
        UpdateRequest request = new UpdateRequest("student", "1");
        Student student = new Student();
        student.setRemark("very good man");
        //doc,指定字段修改
        request.doc(JSONObject.toJSONString(student), XContentType.JSON);
        try {
            UpdateResponse updateResponse = restHighLevelClient.update(request, RequestOptions.DEFAULT);
            System.out.println(updateResponse.getResult());//UPDATED
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //3.修改文档
    @Test
    public void getDoc(){
        GetRequest request = new GetRequest("student", "1");
        try {
            GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
            System.out.println(response.getSourceAsString());//{"age":18,"name":"robin","remark":"very good man"}
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //4.批量操作
    @Test
    public void bulkDocument(){
        BulkRequest bulkRequest = new BulkRequest();
        Student student = new Student();
        for(int i=0;i<10;i++){
            student.setAge(18 + i);
            student.setName("robin" + i);
            student.setRemark("good man " + i);
            bulkRequest.add(new IndexRequest("student")
                    .id(String.valueOf(10 + i))
                    .source(JSONObject.toJSONString(student), XContentType.JSON));
        }
        try {
            BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
            for(BulkItemResponse itemResponse : response.getItems()){
                System.out.println(itemResponse.isFailed());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //5.删除文档
    @Test
    public void deleteDoc(){
        DeleteRequest request = new DeleteRequest("student", "1");
        try {
            DeleteResponse delete = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
            System.out.println(delete.getResult());//DELETED
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4、DSL操作

@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticSearchDSLTest {

    private static final String MY_INDEX = "my_index";
    @Autowired
    RestHighLevelClient restHighLevelClient;
    @Test
    public void testResthightLevelClient() throws Exception {
        System.out.println("restHighLevelClient = " + restHighLevelClient);
    }

    /**
     * dsl查询文档:
     * POST /my_index/_search
     * {
     *   "query": {
     *     "match": {
     *       "title": "华为智能手机"
     *     }
     *   }
     * }
     * */
    @Test
    public void search(){
        //创建请求
        SearchRequest searchRequest = new SearchRequest(MY_INDEX);
        //通过构造器封装构造条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery("title","华为智能手机"));

        searchRequest.source(builder);

        try {
            //高级客户端发送请求,设置默认参数
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

            for(SearchHit hit : searchResponse.getHits().getHits()){
                System.out.println(hit.getSourceAsString());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //高亮查询
    @Test
    public void highlightSearch(){
        SearchRequest request = new SearchRequest(MY_INDEX);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery("title","华为智能手机"));
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.preTags("<b style='color:red'>");
        highlightBuilder.postTags("</b>");
        builder.highlighter(highlightBuilder);
        request.source(builder);
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            for(SearchHit hit : response.getHits().getHits()){
                System.out.println(hit.getSourceAsMap().get("title") + ":" +hit.getHighlightFields().get("title").fragments()[0].string());
                //华为手机:<b style='color:red'>华为</b>手机
                //华为笔记本电脑:<b style='color:red'>华为</b>笔记本电脑
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //聚合查询
    @Test
    public void aggsSearch() {
        SearchRequest request = new SearchRequest(MY_INDEX);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery());
        AggregationBuilder aggregationBuilder = AggregationBuilders
                .terms("groupby_category").field("category");//桶聚合
        aggregationBuilder.subAggregation(AggregationBuilders.avg("avg_price").field("price"));
        builder.aggregation(aggregationBuilder);
        request.source(builder);
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            Aggregations aggregations = response.getAggregations();
            Terms terms = aggregations.get("groupby_category");
            terms.getBuckets().forEach(bucket -> {
                Avg avg = bucket.getAggregations().get("avg_price");
                System.out.println(bucket.getKeyAsString() + ":" + bucket.getDocCount() + "," + avg.getValue());
                //华为:2,5444.0
                //vivo:1,3600.0
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

二、SpringData Elasticsearch

Spring Data 是一个用于简化数据库、非关系型数据库、索引库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷。

官网:Spring Data

Spring Data Elasticsearch 基于 spring data API 简化 Elasticsearch操作,将原始操作Elasticsearch的客户端API 进行封装 。

1. 搭建工程

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.6.RELEASE</version>
    <relativePath/>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
</dependencies>
<build>
    <plugins>
        <!-- java编译插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
               <source>1.8</source>
               <target>1.8</target>
               <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

2. application.properties

# es服务地址
elasticsearch.host=127.0.0.1
# es服务端口
elasticsearch.port=9200
# 配置日志级别,开启debug日志
logging.level.com.atguigu=debug

3. 启动类

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

4. config

@ConfigurationProperties(prefix = "elasticsearch")
@Configuration
@Data
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
    private String host ;
    private Integer port ;

    //重写父类方法
    @Override
    public RestHighLevelClient elasticsearchClient() {
        RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);
        return restHighLevelClient;
    }

    //get/set…
}

5. 添加实体类 bean 映射对象

@Data
@Document(indexName = "product",shards = 1, replicas = 1)
public class Product implements Serializable {
    @Id
    private Long id;
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String productName;
    @Field(type = FieldType.Integer)
    private Integer store;
    @Field(type = FieldType.Double, index = true, store = false)
    private double price;
}

6. dao 数据访问层,继承ElasticsearchRepos,指定映射、主键类型

@Repository
public interface ProductDao extends ElasticsearchRepository<Product,Long> {
}

1、测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticsearchTest {
    @Autowired
    private ElasticsearchRestTemplate elasticsearchTemplate;

    @Autowired
    private ProductDao productDao;
    
    //添加文档
    @Test
    public void saveTest(){
        //框架会隐式执行索引库创建和映射,无需执行下列代码。
        // 创建索引,会根据Product类中的@Document注解信息来创建
        // 配置映射,会根据Product类中的id、Field等字段来自动完成映射
        Product product = new Product();
        product.setId(1L);
        product.setProductName("华为手机");
        product.setStore(100);
        product.setPrice(5000.00);
        productDao.save(product);
        System.out.println("添加成功...");
    }
    @Test
    public void findById(){
        //根据id查询文档
        Product product = productDao.findById(1L).get();
        System.out.println(product);
    }

    @Test
    public void testFind(){
        //查询全部,按照价格降序排序
        Iterable<Product> products = productDao.findAll(Sort.by(Sort.Direction.DESC,"price"));
        System.out.println("products = " + products);

    }
}

2、自定义方法 ★

Spring Data 的另一个强大功能,是根据方法名称自动实现功能。

按照价格区间查询,定义这样的一个接口方法:

List<Product> findByPriceBetween(double price1, double price2);

@Test
public void queryByPriceBetween(){
   List<Product> list = this.productDao.findByPriceBetween(2000.00, 5500.00);
   for (Product product : list) {
       System.out.println("product = " + product);
   }
}
KeywordSampleElasticsearch Query String
AndfindByNameAndPrice{"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
OrfindByNameOrPrice{"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
IsfindByName{"bool" : {"must" : {"field" : {"name" : "?"}}}}
NotfindByNameNot{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}
BetweenfindByPriceBetween{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
LessThanEqualfindByPriceLessThan{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
GreaterThanEqualfindByPriceGreaterThan{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
BeforefindByPriceBefore{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
AfterfindByPriceAfter{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
LikefindByNameLike{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
StartingWithfindByNameStartingWith{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
EndingWithfindByNameEndingWith{"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}
Contains/ContainingfindByNameContaining{"bool" : {"must" : {"field" : {"name" : {"query" : "?","analyze_wildcard" : true}}}}}
InfindByNameIn(Collection<String>names){"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}
NotInfindByNameNotIn(Collection<String>names){"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}}
NearfindByStoreNearNot Supported Yet !
TruefindByAvailableTrue{"bool" : {"must" : {"field" : {"available" : true}}}}
FalsefindByAvailableFalse{"bool" : {"must" : {"field" : {"available" : false}}}}
OrderByfindByAvailableTrueOrderByNameDesc{"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值