elasticsearch8.x高亮和分页

15 篇文章 0 订阅
12 篇文章 0 订阅

elasticsearch8.x高亮和分页

今天咱们就来聊一聊elasticsearch8.x版本如何设置搜索关键词高亮并且分页,因为es7.x和es8.x版本差异比较大,导致了很多es用户在使用时出现了很多问题,es7和es8的高亮就非常不一样,话不多说,直接上代码解释。

如果大家遇到了版本问题或者Java连接不上elasticsearch8.x,可以查看我的这一篇博客elasticsearch 8.7.0的Java API详解教程(一)_不败顽童博主的博客-CSDN博客

@Service
@Slf4j
public class ArticleServiceImpl implements IArticleService {


    @Autowired
    private ElasticSearchArticleMapper elasticSearchArticleMapper;

    @Autowired
    private ElasticsearchClient elasticsearchClient;


    @Autowired
    private KeyWordApi keywordApi;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Page<ArticleIndex> search(PageQueryParam<ArticleDTO> pageQueryParam) {
        //根据一个值查询多个字段  并高亮显示  这里的查询是取并集,即多个字段只需要有一个字段满足即可
        //需要查询的字段
        List<ArticleIndex> result = new ArrayList<>();
        SearchResponse<Map> searchResponse = null;
        try {
            searchResponse = elasticsearchClient.search(srBuilder -> srBuilder
                            .index("article")
                            // MultiMatch 查找:对输入内容先分词再查询。
                            .query(queryBuilder -> queryBuilder
                                    .multiMatch(multiMatchQueryBuilder -> multiMatchQueryBuilder
                                            .fields("title", "summary", "titleEn","plainTextBody")
                                            .query(pageQueryParam.getParam().getKeywords())
                                            .operator(Operator.Or))

                            )
                            // 高亮查询
                            .highlight(highlightBuilder -> highlightBuilder
                                            .preTags("<font color='red'>")
                                            .postTags("</font>")
                                            .requireFieldMatch(true) //多字段时,需要设置为false
//                                    .fields("title", highlightFieldBuilder -> highlightFieldBuilder)
                                            .fields("title", highlightFieldBuilder -> highlightFieldBuilder)
                                            .fields("titleEn", highlightFieldBuilder -> highlightFieldBuilder)
                                            .fields("summary", highlightFieldBuilder -> highlightFieldBuilder)
                                            .fields("plainTextBody", highlightFieldBuilder -> highlightFieldBuilder)
                            )
                            .from(pageQueryParam.getPageNo())
                            .size(pageQueryParam.getPageSize())
                            .sort(sortOptionsBuilder -> sortOptionsBuilder
                                    .field(fieldSortBuilder -> fieldSortBuilder
                                            .field("_score").order(SortOrder.Desc)
                                            /*.field("publishedAt").order(SortOrder.Desc)*/))

                    , Map.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // 高亮并且分页
        List<Hit<Map>> hits = searchResponse.hits().hits();
        for (Hit<Map> hit : hits) {
            Map<String, Object> docMap = hit.source();
            String json = JSON.toJSONString(docMap);
            ArticleIndex articleIndex = JSON.parseObject(json, ArticleIndex.class);
            Map<String, List<String>> highlight = hit.highlight();
            articleIndex.setTitle(highlight.get("title") == null ? articleIndex.getTitle() : highlight.get("title").get(0));
            articleIndex.setTitleEn(highlight.get("titleEn") == null ? articleIndex.getTitleEn() : highlight.get("titleEn").get(0));
            articleIndex.setSummary(highlight.get("summary") == null ? articleIndex.getSummary() : highlight.get("summary").get(0));
            articleIndex.setPlainTextBody(highlight.get("plainTextBody") == null ? articleIndex.getPlainTextBody() : highlight.get("plainTextBody").get(0));
            result.add(articleIndex);
        }
        Page<ArticleIndex> page = new Page<ArticleIndex>();
        page.setRows(result);
        page.setPageNum(pageQueryParam.getPageNo());
        page.setPageSize(pageQueryParam.getPageSize());
        page.setTotalCount(searchResponse.hits().total().value());
        page.setTotalPages((page.getTotalCount() + page.getPageSize() - 1) / page.getPageSize());

        return page;
    }

当中page分页是作者自己编写的一个简单的分页

@Data
public class Page<T> {

    /**
     * 当前页数
     */
    private Integer pageNum = 1;

    /**
     * 当前显示行数
     */
    private Integer pageSize = 10;

    /**
     * 总页数
     */
    private Long totalPages = 0L;

    /**
     * 总行数
     */
    private Long totalCount = 0L;

    /**
     * 是否为最后一页
     */
    private boolean last = false;

    /**
     * 判断第一页
     */
    private boolean first = true;

    private List<T> rows = new ArrayList<T>();

}

下面是article索引实体类

@Data
@Document(indexName = "article")
public class ArticleIndex {

    private static final long serialVersionUID = 132913819042348092L;

    /**
     * 主键
     */
    @Id
    private Long id;

    /**
     * 作者
     */
    @Field(store = true, type = FieldType.Keyword)
    private Long userId;

    /**
     * 文章標題
     */
    @Field(store = true, type = FieldType.Text, analyzer = "ik_smart")
    private String title;

    /**
     * 英文文章標題
     */
    @Field(store = true, type = FieldType.Text, analyzer = "ik_smart")
    private String titleEn;



    /**
     * 文章原始详情
     */
    @Field(store = true, type = FieldType.Text, analyzer = "ik_smart")
    private String plainTextBody;

    /**
     * 會員限定
     */
    @Field(store = true, type = FieldType.Keyword)
    private Boolean memberOnly;

    /**
     * 申請首頁輪播圖
     */
    @Field(store = true, type = FieldType.Keyword)
    private Boolean applyHomepageCarousel;

    /**
     *
     */
    @Field(store = true, type = FieldType.Text, analyzer = "ik_smart")
    private String ogTitle;

    /**
     * SEO用的主前綴
     */
    @Field(store = true, type = FieldType.Text, analyzer = "ik_smart")
    private String parentPath;

    /**
     * SEO用的副前綴
     */
    @Field(store = true, type = FieldType.Text, analyzer = "ik_smart")
    private String childPath;

    /**
     *
     */
    @Field(store = true, type = FieldType.Keyword)
    private String slug;

    /**
     * 點擊數
     */
    @Field(store = true, type = FieldType.Keyword)
    private Long clicksCount;

    /**
     * 留言數
     */
    @Field(store = true, type = FieldType.Keyword)
    private Object commentsCount;

    /**
     * 完成文章時間 (待審核)
     */
    @Field(index = false, store = true, type = FieldType.Date, format = DateFormat.date_optional_time,ignoreMalformed = true)
    private Date completedAt;

    /**
     * 通過審核時間
     */
    @Field(index = false, store = true, type = FieldType.Date, format = DateFormat.date_optional_time,ignoreMalformed = true)
    private Date verifiedAt;

    /**
     * 發佈時間
     */
    @Field(index = false, store = true, type = FieldType.Date, format = DateFormat.date_optional_time,ignoreMalformed = true)
    private Date publishedAt;

    /**
     * 下架時間
     */
    @Field(index = false, store = true, type = FieldType.Date, format = DateFormat.date_optional_time,ignoreMalformed = true)
    private Date expiredAt;

    /**
     * 刪除時間
     */
    @Field(index = false, store = true, type = FieldType.Date, format = DateFormat.date_optional_time,ignoreMalformed = true)
    private Date deletedAt;

    /**
     *
     */
    @Field(index = false, store = true, type = FieldType.Date, format = DateFormat.date_optional_time,ignoreMalformed = true)
    private Date createdAt;

    /**
     *
     */
    @Field(index = false, store = true, type = FieldType.Date, format = DateFormat.date_optional_time,ignoreMalformed = true)
    private Date updatedAt;

    /**
     * 註冊人數
     */
    @Field(store = true, type = FieldType.Keyword)
    private Long viaCount;

    /**
     * 特派員
     */
    @Field(store = true, type = FieldType.Keyword)
    private Long reporterId;

    /**
     * 預覽密碼
     */
    @Field(store = false, type = FieldType.Keyword)
    private String previewPasscode;

    /**
     * 內容摘要
     */
    @Field(store = true, type = FieldType.Text, analyzer = "ik_smart")
    private String summary;

    /**
     * Optimistic Lock
     */
    @Field(store = false, type = FieldType.Keyword)
    private Object lockVersion;

    /**
     * 作者
     */
    @Field(store = true, type = FieldType.Keyword)
    private String authorName;


    /**
     * author_url
     */
    @Field(store = true, type = FieldType.Keyword)
    private String authorUrl;

    /**
     * categories
     */
    @Field(store = true, type = FieldType.Keyword)
    private String categories;

    /**
     * json格式类别
     */
    @Field(store = true, type = FieldType.Object)
    private List<CategoryVO> category;

    /**
     * 图片链接
     */
    @Field(store = true)
    private String imageUrl;


    /**
     * 类型
     */
    @Field(store = true, type = FieldType.Keyword)
    private String type;
}

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

JavaGPT

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值