阅读 398

Elasticsearch 入门级简单使用

Elasticsearch 简单使用

ES 客户端创建及引用

RestHighLevelClient 方式
@Bean public RestHighLevelClient restHighLevelClient() {     return new RestHighLevelClient(             RestClient.builder(                     Arrays.stream(StringUtils.split(ipAddress,                                                     ",")).map(HttpHost::create).toArray(HttpHost[]::new)             )     ); } // 引用使用 @Resource private RestHighLevelClient restHighLevelClient; 复制代码

ElasticsearchTemplate 方式
@Resource private ElasticsearchTemplate elasticsearchTemplate; 复制代码

SpringbootData Repository 方式
1. 实体对象
@Data @AllArgsConstructor @NoArgsConstructor @Document(indexName = CenterShopifyMailAnalysisMessageDO.INDEX_NAME) public class CenterShopifyMailAnalysisMessageDO {          /**      * 索引名称      */     public static final String INDEX_NAME = "shopify_mail_analysis_message";     /**      * 主键      */     @Id     private String id; } 复制代码

2. 创建Mapper
@Repository public interface CenterShopifyMailAnalysisMessageRepository extends ElasticsearchRepository<CenterShopifyMailAnalysisMessageDO, String> {     /**      * 原始索引ID      *      * @param refOriginalMessageId      * @return CenterShopifyMailAnalysisMessageDO      */     CenterShopifyMailAnalysisMessageDO findByRefOriginalMessageId(String refOriginalMessageId);     /**      * 查询总条数      *      * @return 总条数      */     int countAllBy(); } 复制代码

3. 引用使用
@Resource private CenterShopifyMailAnalysisMessageRepository centerShopifyMailAnalysisMessageRepository; 复制代码

ES 查询常用方法汇总

方法说明
filter不计算评分, 查询效率高,有缓存 (推荐)
must要计算评分,查询效率低,无缓存
must_not条件不需要满足
term不会对输入得内容进行分词
match会对输入得内容进行分词
matchPhrase短语匹配查询,ES引擎首先分析查询字符串,从分析后的文本中构建短语查询,这意味着必须匹配短语中的所有分词,并且保证各个分词的相对位置不变
wildcard通配符查询,*:表示o个或多个字符,?: 表示单个字符; 类似于mysql 中得 like 查询
rangegte:大于等于,gt:大于,lte: 小于等于,lt:小于,from-to 相当于 between
exists查询文档中是否包含field指定的字段,例如:查询不为null :builder.must(QueryBuilders.existsQuery("字段名"));查询不为空字符串 builder.mustNot(QueryBuilders.termQuery("字段名", ""));
prefix匹配分词前缀 如果字段没分词,就匹配整个字段前缀
idx根据id查询
FetchSourceFilterBuilder : 对象可以设置哪些属性输出哪些不输出 复制代码
Script: 可以用作查询也可以用作排序      查询:  // 查询当前时间-sentDateTime >= 86400000 的数据 Script script = new Script("new Date().getTime() - doc['sentDateTime'].value >= 86400000"); builder.filter(QueryBuilders.scriptQuery(script)); 排序: // replyStatus为0时,sentDateTime按从小到大排序,replyStatus不为0时,sentDateTime按从大到小排序 Script script = new Script("if(doc['replyStatus'].value == 0){return doc['sentDateTime'].value * -1 }else{return doc['sentDateTime'].value}"); ScriptSortBuilder scriptSortBuilder = SortBuilders.scriptSort(script, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC); SearchQuery searchQuery = new NativeSearchQueryBuilder()                 .withQuery(builder)                 .withSort(scriptSortBuilder                 .build(); 复制代码

ES 查询示例

term 查询

term做精确查询可以用它来处理数字,布尔值,日期以及文本。查询数字时问题不大,但是当查询字符串时会有问题。term查询的含义是termQuery会去倒排索引中寻找确切的term,但是它并不知道分词器的存在。term表示查询字段里含有某个关键词的文档,terms表示查询字段里含有多个关键词的文档。也就是说直接对字段进行term本质上还是模糊查询,只不过不会对搜索的输入字符串进行分词处理罢了。如果想通过term查到数据,那么term查询的字段在索引库中就必须有与term查询条件相同的索引词,否则无法查询到结果。

一句话解释: elasticsearch 里默认的IK分词器是会将每一个中文都进行了分词的切割,所以你直接想查一整个词,或者一整句话是无返回结果的。

关于keyword:

我看有的文章说设置该属性用于关键词搜索,不进行分词。对于字符串类型的字段,es会默认生成一个keyword字段用于精确搜索。也有的说实际上还是会分词,只不过keyword的设置增加了一个额外字段,该字段就是filename.keyword。这个keyword才是不分词的索引字段,也就真正意义上实现了不分词处理字段。索引也是索引该字段才生成真正的精确匹配。至于分不分词实验一下就好了。感觉他们想表达的意思差不多是filename.keyword不分词,但是filename还是会分词。

public ResponseResult<List<CenterShopifyMailAnalysisMessageVO>> queryPage(CenterShopifyEmailReqVO entity) {     BoolQueryBuilder builder = QueryBuilders.boolQuery();     // 精确查询     builder.filter(QueryBuilders.termQuery("websiteId", entity.getWebsiteId()));          // 如果用term查询字符串的话,请注意上面引用语句,否则可能导致查询到意想不到的结果,term 字符串精确查询的话,用keyword     // 字符串精确查询     builder.filter(QueryBuilders.termQuery("name.keyword", entity.getName));          // 时间范围查询, between     builder.filter(QueryBuilders.rangeQuery(CenterShopifyMailConstant.SENT_DATETIME)                    .from(DateUtil.parseDateTime(entity.getStartTime()).getTime())                    .to(DateUtil.parseDateTime(entity.getEndTime()).getTime()));          // 发件人,模糊查询,例如 like '%xx%'     builder.filter(QueryBuilders.wildcardQuery("sendAddress.keyword", "*" +                                                 centerShopifyEmailReqVO.getFromBy() + "*"));          // 主题,模糊查询,默认中文分词,和 like 有区别     builder.filter(QueryBuilders.matchPhraseQuery("subject", entity.getSubject()));          // 订单 例如: and ( orderNo=xx or orderNo=xx )     BoolQueryBuilder order = new BoolQueryBuilder();     entity.getOrderNoList().forEach(o -> order.should(QueryBuilders.matchPhraseQuery("orderNo", o)));     builder.filter(order);          // 标签 例如: and ( refLabelId like '%xx%' and refLabelId like '%xx%' )     entity.getLabelIds().forEach(o ->                     builder.must(QueryBuilders.wildcardQuery("refLabelId.keyword",                                                              "*" + o +"*")));          if (centerShopifyEmailReqVO.getFinishStart() == 3) {         // 24 小时内未处理         Script script = new Script("new Date().getTime() - doc['sentDateTime'].value < 86400000");         builder.filter(QueryBuilders.scriptQuery(script));     } else if (centerShopifyEmailReqVO.getFinishStart() == 4) {         // 大于24小时未处理         Script script = new Script("new Date().getTime() - doc['sentDateTime'].value >= 86400000");         builder.filter(QueryBuilders.scriptQuery(script));     }          // 排序 replyStatus=0,sentDateTime从小到大排序, 等于0 乘以-1的目的是让返回的数值调个个儿     //      replyStatus≠0,sentDateTime从大到小排序,     Script script = new Script("if(doc['replyStatus'].value == 0){return doc['sentDateTime'].value * -1                                }else{return doc['sentDateTime'].value}");     ScriptSortBuilder scriptSortBuilder = SortBuilders.scriptSort(script,                                           ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC);     // body 设置不输出     FetchSourceFilterBuilder fetchSourceFilterBuilder = new FetchSourceFilterBuilder();     fetchSourceFilterBuilder.withExcludes(CenterShopifyMailConstant.BODY);     SearchQuery searchQuery = new NativeSearchQueryBuilder()             .withQuery(builder)             .withSort(SortBuilders.fieldSort(CenterShopifyMailConstant.STATUS).order(SortOrder.ASC))             .withSort(scriptSortBuilder)             .withSourceFilter(fetchSourceFilterBuilder.build())             .withPageable(PageRequest.of(entity.getCurrentPage() - 1, entity.getPageSize()))             .build();     AggregatedPage<CenterShopifyMailAnalysisMessageDO> centerShopifyMailAnalysisMessageDOS =                                elasticsearchTemplate.queryForPage(searchQuery,                                                                   CenterShopifyMailAnalysisMessageDO.class);         // content 返回数据,getTotalElements 总条数     return ResponseResult.successPage(content, centerShopifyMailAnalysisMessageDOS.getTotalElements(),                                       centerShopifyEmailReqVO.getCurrentPage(),                                       centerShopifyEmailReqVO.getPageSize()); }


作者:时光清浅、许你心安
链接:https://juejin.cn/post/7018078585780961316


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐