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 查询 |
range | gte:大于等于,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