SpringBoot整合ElasticSearch

7 SpringBoot整合ElasticSearch

7.1 导入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
7.2 写yml
spring:
  elasticsearch:
    rest:
      uris: 127.0.0.1:9200 #地址
7.3 实体映射
package com.cxs.elasticsearch.entity;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.time.LocalDateTime;

/*
 * @Author:cxs
 * @Motto:放下杂念,只为迎接明天更好的自己
 * */
@Data
@Document(indexName = "good_item_index")
public class GoodItem {
    @Id
    private Long id;
    @Field(type = FieldType.Long)
    private Long spu;
    @Field(type = FieldType.Long)
    private Long sku;
    @Field(type = FieldType.Text)
    private String title;
    @Field(type = FieldType.Long)
    private Long price;
    @Field(type = FieldType.Text)
    private String pic;
    @Field(type = FieldType.Text)
    private String url;
    @Field(type = FieldType.Date, format = DateFormat.date)
    private LocalDateTime createTime;
    @Field(type = FieldType.Date, format = DateFormat.date)
    private LocalDateTime updateTime;
}
7.4 Dao
package com.cxs.elasticsearch.dao;

import com.cxs.elasticsearch.entity.GoodItem;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;

/*
 * @Author:cxs
 * @Motto:放下杂念,只为迎接明天更好的自己
 * */
@Repository
public interface GoodItenDao extends ElasticsearchRepository<GoodItem, Long> {

}
7.5 Service
package com.cxs.service.impl;

import com.cxs.elasticsearch.dao.GoodItenDao;
import com.cxs.elasticsearch.entity.GoodItem;
import com.cxs.service.GoodService;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*
 * @Author:cxs
 * @Motto:放下杂念,只为迎接明天更好的自己
 * */
@Service
public class GoodServiceImpl implements GoodService {
    @Autowired
    private GoodItenDao goodItenDao;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public Boolean save(GoodItem goodItem) {
        GoodItem save = goodItenDao.save(goodItem);
        System.out.println(save);
        return save != null;
    }

    @Override
    public List<GoodItem> findAll() {
        Iterable<GoodItem> all = goodItenDao.findAll();
        List<GoodItem> list = new ArrayList<>();
           all.forEach(a -> {
               list.add(a);
           });
        return list;
    }

    @Override
    public List<GoodItem> search(GoodItem goodItem) {
        Iterable<GoodItem> search = goodItenDao.search(QueryBuilders.termsQuery("url", goodItem.getUrl()));
        List<GoodItem> list = new ArrayList<>();
        search.forEach(a -> {
            list.add(a);
        });
        return list;
    }

    @Override
    public List<GoodItem> query(GoodItem goodItem) {
        List<GoodItem> list = new ArrayList<>();
        GoodItem item = elasticsearchRestTemplate.get("", GoodItem.class);
        return list;
    }
}
7.6 测试
//  ... 测试省略
7.7 复杂查询

ElasticsearchRepository中许多方法已经被弃用,实现复杂操作就需要自己实现,注入

ElasticsearchRestTemplate完成复杂操作,注意,原先的ElasticsearchTemplate已经弃用

7.7.1 使用ElasticsearchRestTemplate完成Match查询
// 匹配url is https://item.jd.com/100016034400.html
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("url", "https://item.jd.com/100016034400.html");
NativeSearchQuery query = new NativeSearchQuery(matchQueryBuilder);
SearchHits<GoodItem> search = elasticsearchRestTemplate.search(query, GoodItem.class);
List<SearchHit<GoodItem>> hits = search.getSearchHits();
List<GoodItem> list = new ArrayList<>();
// 总数
long totalHits = search.getTotalHits();
for (SearchHit<GoodItem> hit : hits) {
    GoodItem content = hit.getContent();
    list.add(content);
}
System.out.println(list);
7.7.2 使用ElasticsearchRestTemplate完成Bool查询
    @Test
    void contextLoads1() {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("url", "https://item.jd.com/100016034400.html");
        TermQueryBuilder termQuery = QueryBuilders.termQuery("url", "https://item.jd.com/100016034400.html");
        boolQueryBuilder.should(matchQuery).should(termQuery);
        NativeSearchQuery query = new NativeSearchQuery(boolQueryBuilder);
        SearchHits<GoodItem> search = elasticsearchRestTemplate.search(query, GoodItem.class);
        System.out.println(search);
        List<SearchHit<GoodItem>> hits = search.getSearchHits();
        List<GoodItem> list = new ArrayList<>();
        long totalHits = search.getTotalHits();
        for (SearchHit<GoodItem> hit : hits) {
            GoodItem content = hit.getContent();
            list.add(content);
        }
        System.out.println(list);
    }
7.7.3 Es批量操作,存在即修改,不存在即插入
    @Test
    void contextLoads1() {
        BulkRequest bulkRequest = new BulkRequest();
        for (FinancialDoc document : documents) {
            document.setProdId(getProductId(document));
            document.setRefreshTime(LocalDateTime.now());
            IndexRequest indexRequest = new IndexRequest(getIndex())
                    .id(document.getProdId())
                    .source(JSON.toJSONString(document), XContentType.JSON);
            UpdateRequest request = new UpdateRequest(getIndex(), document.getProdId())
                    .doc(JSON.toJSONString(document), XContentType.JSON).upsert(indexRequest);
            bulkRequest.add(request);
        }
        BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        return bulkResponse.status().equals(RestStatus.OK);
    }
7.7.4 Es全量查询文档,总数大于10000条

使用scroll,每次1000条查询,可自行调整

public List<StockDoc> selectAllList() throws IOException {
        SearchRequest request = new SearchRequest();
        request.indices(getIndex());
        List<StockDoc> result = new ArrayList<>();
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.size(1000).query(QueryBuilders.matchAllQuery());
        Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L));
        request.scroll(scroll)
                .source(builder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        String scrollId = searchResponse.getScrollId();
        SearchHit[] searchHits = searchResponse.getHits().getHits();
        while (searchHits != null && searchHits.length > 0) {
            SearchHits hits = searchResponse.getHits();
            for (SearchHit hit : hits) {
                result.add(JSON.parseObject(hit.getSourceAsString(), StockDoc.class));
            }
            SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
            scrollRequest.scroll(scroll);
            searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);
            searchHits = searchResponse.getHits().getHits();
        }
        ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
        clearScrollRequest.addScrollId(scrollId);
        client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
        return result;
    }
7.7.5 复杂搜索-权重,优先级排序
private void globalSearchConditionHandler(SearchDTO dto, SearchSourceBuilder builder) {
        // 封装分页数据
        builder.from((dto.getPageNum() - 1) * dto.getPageSize());
        builder.size(dto.getPageSize());
        Script script =
                new Script("if (doc['code.keyword'].value == '" + dto.getKeyword() + "') {return doc['code.keyword'].value.length();} else {if(doc['codeType.keyword'].value == '4353' || doc['codeType.keyword'].value == '4609') {return 1;} else {return 0;}}");
        Script codeTypeScript =
                new Script("return Integer.parseInt(doc['codeType.keyword'].value)");
        SortBuilder sortBuilder = SortBuilders.scriptSort(script, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC);
        SortBuilder codeTypeScriptBuild = SortBuilders.scriptSort(codeTypeScript, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.ASC);
        SortBuilder scoreBuild = SortBuilders.fieldSort("_score").order(SortOrder.DESC);
        SortBuilder codeBuild = SortBuilders.fieldSort("code.keyword").order(SortOrder.ASC);
        builder.sort(scoreBuild);
        builder.sort(sortBuilder);
        builder.sort(codeTypeScriptBuild);
        builder.sort(codeBuild);
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if (StringUtils.hasLength(dto.getKeyword())) {
            BoolQueryBuilder query = QueryBuilders.boolQuery();
            query.should(QueryBuilders.wildcardQuery("code.keyword", swapLeftKey(dto.getKeyword())).boost(100.0f))
                    .should(QueryBuilders.wildcardQuery("code.keyword", swapKey(dto.getKeyword())).boost(90.0f))
                    .should(QueryBuilders.wildcardQuery("codeName.keyword", swapLeftKey(dto.getKeyword())).boost(10.0f))
                    .should(QueryBuilders.wildcardQuery("codeName.keyword", swapKey(dto.getKeyword())).boost(9.5f))
                    .should(QueryBuilders.wildcardQuery("pinYin.keyword", swapLeftKey(dto.getKeyword())).boost(9.0f))
                    .should(QueryBuilders.wildcardQuery("pinYin.keyword", swapLeftKey(dto.getKeyword().toUpperCase(Locale.ROOT))).boost(9.0f))
                    .should(QueryBuilders.wildcardQuery("pinYin.keyword", swapLeftKey(dto.getKeyword().toUpperCase(Locale.ROOT))).boost(9.0f))
                    .should(QueryBuilders.regexpQuery("pinYin.keyword", regexStr(dto.getKeyword().toUpperCase(Locale.ROOT))).boost(8.0f))
                    .should(QueryBuilders.regexpQuery("pinYin.keyword", regexStr(dto.getKeyword().toLowerCase(Locale.ROOT))).boost(8.0f))
                    .should(QueryBuilders.wildcardQuery("pinYin.keyword", swapKey(dto.getKeyword())).boost(7.0f))
                    .should(QueryBuilders.wildcardQuery("pinYin.keyword", swapKey(dto.getKeyword().toUpperCase(Locale.ROOT))).boost(7.0f))
                    .should(QueryBuilders.wildcardQuery("pinYin.keyword", swapKey(dto.getKeyword().toLowerCase(Locale.ROOT))).boost(7.0f));
            boolQuery.must(query);
        }
        builder.query(boolQuery);
    }

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是SpringBoot整合elasticsearch的步骤: 1. 引入elasticsearchspring-boot-starter-data-elasticsearch的依赖: ``` <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>7.12.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> <version>2.4.5</version> </dependency> ``` 2. 配置elasticsearch连接信息: ``` spring.data.elasticsearch.cluster-nodes=localhost:9200 ``` 3. 创建实体类: ``` @Document(indexName = "my_index") public class MyEntity { @Id private String id; private String name; // getter and setter } ``` 4. 创建es的Repository: ``` public interface MyRepository extends ElasticsearchRepository<MyEntity, String> { } ``` 5. 在service中使用Repository: ``` @Service public class MyService { @Autowired private MyRepository myRepository; public void save(MyEntity entity) { myRepository.save(entity); } public List<MyEntity> search(String name) { return myRepository.findByName(name); } } ``` 6. 在controller中调用service: ``` @RestController public class MyController { @Autowired private MyService myService; @PostMapping("/save") public void save(@RequestBody MyEntity entity) { myService.save(entity); } @GetMapping("/search") public List<MyEntity> search(@RequestParam String name) { return myService.search(name); } } ``` 这样就可以通过SpringBoot整合elasticsearch实现数据的增删改查了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈小白.

感谢老板,祝老板今年发大财!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值