目录


网上教程多是Elasticsearch旧版本,很多方法已弃用,本文以Elasticsearch 7.10.1,SpringBoot 2.3.6.RELEASE为例说明如何整合:

一、添加pom依赖

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.um.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>1.0.0-SNAPSHOT</version>

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

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </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>
</project>

二、application.yml文件配置

spring:
  elasticsearch:
    rest:
      uris: http://10.211.55.8:9200

三、实体类及注解

Spring Data通过注解来声明字段的映射属性,有下面的三个注解:

  • @Document 作用在类,标记实体类为文档对象,一般有四个属性

    • indexName:对应索引库名称
    • shards:分片数量,默认5
    • replicas:副本数量,默认1
  • @Id 作用在成员变量,标记一个字段作为id主键
  • @Field 作用在成员变量,标记为文档的字段,并指定字段映射属性:

    • type:字段类型,取值是枚举:FieldType
    • index:是否索引,布尔类型,默认是true
    • store:是否存储,布尔类型,默认是false
    • analyzer:分词器名称:ik_max_word

示例代码:

@Document(indexName = "item", shards = 1, replicas = 0)
public class Item {
    @Id
    private Long id;
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String title;
    @Field(type = FieldType.Keyword)
    private String category;
    @Field(type = FieldType.Keyword)
    private String brand;
    @Field(type = FieldType.Double)
    private Double price;
    @Field(type = FieldType.Keyword, index = false)
    private String images;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public String getImages() {
        return images;
    }

    public void setImages(String images) {
        this.images = images;
    }
}

四、Elasticsearch索引操作

1、创建索引

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

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Test
    public void testCreateIndex(){
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(Item.class);
        Document mapping = indexOperations.createMapping();
        indexOperations.putMapping(mapping);
    }
}

2、删除索引

    @Test
    public void testDeleteIndex() {
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(Item.class);
        indexOperations.delete();
    }

五、Elasticsearch文档操作

1、新增/修改文档

定义接口ItemRepository继承ElasticsearchRepository

public interface ItemRepository extends ElasticsearchRepository<Item, Long> {

    List<Item> findByTitle(String title);

    List<Item> findByPriceBetween(Double d1,Double d2);
}

新增文档

    @Test
    public void testCreate() {
        Item item = new Item(1L, "小米手机7", " 手机", "小米", 3499.00, "http://image.leyou.com/13123.jpg");
        itemRepository.save(item);
    }

2、删除文档

    @Test
    public void testDelete() {
        itemRepository.deleteById(1L);
    }

3、基本查询

    @Test
    public void testFind() {
        Iterable<Item> items = itemRepository.findAll(Sort.by("price").descending());
        items.forEach(System.out::println);
    }

    @Test
    public void testFindByTitle() {
        List<Item> items = itemRepository.findByTitle("手机");
        items.forEach(System.out::println);
    }

    @Test
    public void testFindByPriceBetween() {
        List<Item> items = itemRepository.findByPriceBetween(3699D, 4499D);
        items.forEach(System.out::println);
    }

4、高级查询

    @Test
    public void testSearch() {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(QueryBuilders.matchQuery("title", "手机"));
        int page = 0;
        int size = 1;
        queryBuilder.withPageable(PageRequest.of(page, size));
        SearchHits<Item> hits = elasticsearchRestTemplate.search(queryBuilder.build(), Item.class);
        List<Item> items = hits.stream().map(SearchHit::getContent).collect(Collectors.toList());
        items.forEach(System.out::println);
    }

5、聚合查询

    @Test
    public void testAgg() {
        // 初始化自定义查询构建器
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 添加聚合,嵌套聚合求平均值
        queryBuilder.addAggregation(AggregationBuilders.terms("brandAgg").field("brand")
                .subAggregation(AggregationBuilders.avg("price_avg").field("price")));
        // 添加结果集过滤,不包括任何字段
        queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{}, null));
        // 执行聚合查询,获取分组数据
        SearchHits<Item> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(), Item.class);
        Terms terms = (Terms) searchHits.getAggregations().asMap().get("brandAgg");
        List<? extends Terms.Bucket> buckets = terms.getBuckets();
        buckets.forEach(bucket -> {
            System.out.println(bucket.getKeyAsString());
            System.out.println(bucket.getDocCount());
            Map<String, Aggregation> stringAggregationMap = bucket.getAggregations().asMap();
            Avg price_avg = (Avg) stringAggregationMap.get("price_avg");
            System.out.println(price_avg.getValue());
        });
    }
©本文为原创文章,著作权归博主所有,转载请联系博主获得授权

发表评论