Elasticsearch(ES)多条件过滤实现案例

本文介绍了如何在Elasticsearch中进行高效的查询操作,包括使用match_phrase查询、优化索引结构以及采用最新版本的Elasticsearch等方法。此外,还提供了具体的Java示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

要完成上述图片上的查询条件,也即需要同时符合多种过滤条件。

由于公司的服务器中安装的elasticsearch版本很老,升级不是很方便,所以是基于老版本,新版本相应的语句做一些改变也可以。

实现:(具体条件需要更改)(elasticsearch版本:2.3.2)

实现代码
 

潜在优化:

1. "should": [

                        {"match_phrase": {"termID": "00:23:A5:30:45:AD"}},
                        {"match_phrase": {"material_id": "1520"}},
                        {"match_phrase": {"material_id": "1521"}}

],

"minimum_should_match": 2,

这个匹配可能是比较耗时的,采用match_phrase主要是因为低版本string类型,且创建index时,没有设置为not_anlyzed。

改成not_anlyzed(新版本用keyword类型,index=true),用filter - terms也许效率会提升;

2. 按项目而不是日期来定义索引,这样搜索范围将会大大缩小;

3. 采用最新版本elasticsearch,采用painless语言。

 

补充:

1. version:6.3(改良优化后)的实现代码:

6.3实现代码

2. 日期范围限定、字符串排序还可以通过keyword属性来很方便地实现:

curl -XGET 'localhost:9200/doc.default.terminal_crash/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "sort": {
    "level.keyword": {
      "order": "desc"
    }
  },
  "query" : {
    "bool" : {
      "filter": {
        "range" : {
          "when.keyword" : {
            "from" : "2019-12-29 00:00:00", "to" : "2019-12-31 00:00:00"
          }
        }
      }
    }
  }
}
'

3. Java版本的示例(由于业务不一样,所以与本例的查询条件不一样,但是可以参考):

public MyResponse searchPlayRecords(Date startDate, Date endDate, String mac, String keyword, MyPage page) throws Exception {
        // 排序条件
        FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("end_time.keyword").order(SortOrder.DESC);
        // 查询条件
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.matchPhraseQuery("device_id", mac));
        if (keyword != null && !keyword.trim().isEmpty()) {
            keyword = "*" + keyword.trim().toLowerCase() + "*";
            queryBuilder.must(QueryBuilders.boolQuery().should(QueryBuilders.wildcardQuery("name", keyword))
                    .should(QueryBuilders.wildcardQuery("channel_name", keyword)));
        }
        // 执行条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().sort(fieldSortBuilder).from((page.getNumber() - 1) * page.getSize())
                .size(page.getSize()).query(queryBuilder);
        if (startDate.compareTo(endDate) >= 0) return new MyResponse(MyStatusCode.DATE_SRART_EXCEED_END, "");
        String[] indice = esService.buildDateIndice(startDate, endDate);
        return new MyResponse(esService.searchRecords(indice, searchSourceBuilder));
    }

说明:在startDate到endDate日期区间内,按照end_time逆序排序,对name和channel_name两个字段模糊查询关键字(两者中有一个包含keyword)。

public MyResponse searchOperationRecords(String startDate, String endDate, String operator, String operand, MyPage page) throws Exception {
        // 排序条件
        FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("time").order(SortOrder.DESC);
        // 查询条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.rangeQuery("time").gt(DateUtils.parseDate(startDate, "yyyy-MM-dd HH:mm:ss").getTime())
                        .lt(DateUtils.parseDate(endDate, "yyyy-MM-dd HH:mm:ss").getTime()));
        if (operator != null) boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("operator", operator));
        if (operand != null) boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("operand", operand));
        // 执行条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().sort(fieldSortBuilder).from((page.getNumber() - 1) * page.getSize())
                .size(page.getSize()).query(boolQueryBuilder);
        String[] indice = { "doc." + springService.getHeader("PROJECT") + ".terminal_operation" };
        return new MyResponse(esService.searchRecords(indice, searchSourceBuilder));
    }

说明:在startDate到endDate日期区间内,按照time逆序,不分词匹配词语operator,operand。

public MyResponse searchCrashDates(String mac, String dateString) throws Exception {
        String monthDateString = dateString.substring(0, 8);
        // 查询条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("device_id", mac)).must(QueryBuilders.matchPhraseQuery("date", monthDateString));
        // 执行条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().size(0).query(boolQueryBuilder)
                .aggregation(AggregationBuilders.terms("DateAggs").field("day.keyword"));
        String[] indice = { "doc." + springService.getHeader("PROJECT") + ".terminal_crash" };
        JSONObject aggregation = esService.aggregateRecords(indice, searchSourceBuilder, "DateAggs");
        return new MyResponse(aggregation.keySet());
    }

说明:根据day聚合,不分词匹配词语device_id,date。

ESService.java

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值