SpringBoot 中使用ElasticSearch并高亮檢索文檔附件內(nèi)容

SpringBoot使用案例

依賴引入

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

配置文件

需要注意的是ES7.0以上的版本是啟用transportClient的也就是9300端口,8.0后會(huì)完全剔除,所以本次用的是http端口9200

示例代碼

DocumentFieldSpringBootES的映射注解支持,就是字面意思

@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("user")
@Document(indexName = "example", type = "user", shards = 1, replicas = 0)
public class User extends BaseModel {

    private static final long serialVersionUID = 1L;
    
    @TableField("user_name")
    @Field(type = FieldType.Keyword)
    private String userName;

    @TableField("password")
    @Field(type = FieldType.Keyword)
    private String password;

    @TableField("age")
    @Field(type = FieldType.Keyword)
    private Integer age;

    @TableField("content")
    @Field(type = FieldType.Text)
    private String content;

    @Field(type = FieldType.Text)
    private String fileData;
    
    //附件類型
    private Attachment attachment;
}
@Data
public class Attachment implements Serializable {
    private static final long serialVersionUID = 1L;

    private String contentType;
    private String author;
    private String language;
    private String title;
    private String content;
}

SpringBoot支持的curl接口,不需要實(shí)現(xiàn)接口,直接注入使用就可以了,但需要方法符合要求

public interface ElasticRepository extends ElasticsearchRepository<User, String> {
    //實(shí)例案例
    Page<User> findByContent(String content, Pageable pageable);
    //實(shí)例案例
    User queryById(String id);
}

使用ingest-attachment 插件高亮檢索文檔內(nèi)容

安裝插件

進(jìn)入ESbin目錄下

#linux下安裝
./elasticsearch-plugin install ingest-attachment 
#window下安裝
./elasticsearch-plugin.bat install ingest-attachment

使用kibana建立管道

-attachment:管道名
-fileData:需要轉(zhuǎn)碼的屬性
-remove:移除掉轉(zhuǎn)碼后的數(shù)據(jù)

#PUT _ingest/pipeline/attachment
{
  "description": "單文件管道流",
  "processors": [
    {
      "attachment": {
        "field": "fileData",
        "ignore_missing": true
      }
    },{
     "remove":{"field":"fileData"}
    }
  ]
}

SpringBoot高亮檢索文件案例
先簡(jiǎn)單了解一下可以使用的API

RestHighLevelClientES官方支持的Api,可以實(shí)現(xiàn)很多操作~~
ElasticsearchRestTemplate:封裝了RestHighLevelClient模板Api,也能支持基本操作
ElasticsearchRepositorySpringBoot支持CurlApi,能實(shí)現(xiàn)基本的操作

索引數(shù)據(jù)

restHighLevelClient官方文檔

  • 使用的是restHighLevelClient,其他沒找到可以設(shè)置管道的地方。。。。。
        User user = new User();
        user.setAge(12);
        user.setContent("asd");
        user.setUserName("asd");
        user.setId("12412412");
        try {
            File file = new File("C:\\Users\\Administrator\\Desktop\\答辯分組名單.xlsx");
            user.setFileData(Base64.encode(file));
            IndexRequest indexRequest = new IndexRequest().setPipeline("attachment").index("example")
                    .type("user").id(user.getId()).source(JSON.toJSONString(user), XContentType.JSON);
            restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }

查詢數(shù)據(jù)

高亮需要自己定義Mapper
邏輯看一下代碼,都是簡(jiǎn)單的案例

    @GetMapping("detailByEs/{id}")
    public Page<User> detailByEs(@PathVariable("id") String id) {
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field(new HighlightBuilder.Field("content"));
        searchQueryBuilder.withPageable(Pageable.unpaged())
                .withQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("attachment.content", id)))
                .withFilter(QueryBuilders.rangeQuery("age").gt(11))
                .withHighlightBuilder(new HighlightBuilder().field("attachment.content"));

        return elasticsearchTemplate.queryForPage(
                searchQueryBuilder.build(), User.class, esResultMapper);
    }
@Component
public class EsResultMapper implements SearchResultMapper {

    @Override
    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, Pageable pageable) {
        // 記錄總條數(shù)
        long totalHits = response.getHits().getTotalHits();
        // 記錄列表(泛型) - 構(gòu)建Aggregate使用
        List<T> list = new ArrayList<>();
        // 獲取搜索結(jié)果(真正的的記錄)
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            if (hits.getHits().length <= 0) {
                return null;
            }
            // 將原本的JSON對(duì)象轉(zhuǎn)換成Map對(duì)象
            Map<String, Object> map = hit.getSourceAsMap();
            // 獲取高亮的字段Map
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            for (Map.Entry<String, HighlightField> highlightField : highlightFields.entrySet()) {
                // 獲取高亮的Key
                String key = highlightField.getKey();
                String[] keys = key.split("\\.");
                key = keys[keys.length - 1];
                // 獲取高亮的Value
                HighlightField value = highlightField.getValue();
                // 實(shí)際fragments[0]就是高亮的結(jié)果,無(wú)需遍歷拼接
                Text[] fragments = value.getFragments();
                StringBuilder sb = new StringBuilder();
                for (Text text : fragments) {
                    sb.append(text);
                }
                // 因?yàn)楦吡恋淖侄伪厝淮嬖谟贛ap中,就是key值
                // 可能有一種情況,就是高亮的字段是嵌套Map,也就是說(shuō)在Map里面還有Map的這種情況,這里沒有考慮
                map.put(key, sb.toString().replaceAll("[\n\t]", ""));
            }

            // 把Map轉(zhuǎn)換成對(duì)象
            map.put("attachment", "");
            T item = JSON.parseObject(JSONObject.toJSONString(map), aClass);
            list.add(item);
        }
        // 返回的是帶分頁(yè)的結(jié)果
        return new AggregatedPageImpl<>(list, pageable, totalHits);
    }

    @Override
    public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
        Map<String, Object> map = searchHit.getSourceAsMap();
        return JSON.parseObject(JSONObject.toJSONString(map), type);
    }

}

參考文章
SpringBoot 中使用ElasticSearch并高亮檢索文檔內(nèi)容_小柒7的博客-CSDN博客
Using the Attachment Processor with arrays | Elasticsearch Plugins and Integrations [7.13] | Elastic

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容