Elasticsearch:search template 初体验

「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」。

最近在用es做搜索服务,反正就是一个新手,各种尝试。

初始版本

直接网上学习了下。自己直接写了个简单的业务。就是搜索.具体代码如下

SearchRequest searchRequest = new SearchRequest();
// 索引名称
searchRequest.indices("general_content");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.from((param.getPageIndex() - 1) * param.getPageSize());
searchSourceBuilder.size(param.getPageSize());
String searchKey = param.getSearchKey();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
        .must(QueryBuilders.termQuery("platformId", param.getPlatformId()))
        .must(QueryBuilders.termQuery("typeCode", param.getTypeCode()))
        .must(QueryBuilders.termQuery("projectCode", param.getProjectCode()))
        .must(QueryBuilders.termQuery("publish", "1"));
if (StringUtils.hasLength(searchKey)) {
    boolQueryBuilder.must(QueryBuilders.multiMatchQuery(searchKey, new String[]{"title", "summary"}).operator(Operator.AND));
}
searchSourceBuilder.query(boolQueryBuilder)
        .sort(SortBuilders.fieldSort("top").order(SortOrder.DESC))
        .sort(SortBuilders.fieldSort("sort").order(SortOrder.DESC))
        .sort(SortBuilders.fieldSort("createdTime").order(SortOrder.DESC));


searchRequest.source(searchSourceBuilder);
List<GeneralContentPO> list = new ArrayList<>();
long totalHits;
try {
    SearchResponse searchResponse;
    searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
    totalHits = searchResponse.getHits().getTotalHits().value;
    if (totalHits > 0) {
        SearchHit[] searchHit = searchResponse.getHits().getHits();
        for (SearchHit hit : searchHit) {
            Map<String, Object> map = hit.getSourceAsMap();
            list.add(objectMapper.convertValue(map, GeneralContentPO.class));
        }
    }
} catch (Exception e) {
    log.error("搜索服务出现异常,异常信息:{}", e);
    throw new SearchException(SearchResultEnum.SEARCH_ERROR);
}
复制代码

一开始 写出来。测试了下 完全没问题。心里那是个高兴

发现新大陆

做搜索服务一直看 这个elastic-search-in-action.medcl.com/ 看到了一个名词 进入我的眼中。 search template

于是乎,尝试了下

构建搜索模板

POST _scripts/content_search_template_v1
{
  "script": {
    "lang": "mustache",
    "source": {
      "from": "{{from}}",
      "size": "{{size}}",
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "platformId": {
                  "value": "{{platformId}}",
                  "boost": 1
                }
              }
            },
            {
              "term": {
                "typeCode": {
                  "value": "{{typeCode}}",
                  "boost": 1
                }
              }
            },
            {
              "term": {
                "projectCode": {
                  "value": "{{projectCode}}",
                  "boost": 1
                }
              }
            },
            {
              "term": {
                "publish": {
                  "value": "{{publish}}",
                  "boost": 1
                }
              }
            },
            {
              "multi_match": {
                "query": "{{query}}",
                "fields": [
                  "summary",
                  "title"
                ],
                "boost": 1
              }
            }
          ]
        }
      },
      "sort": [
        {
          "top": {
            "order": "desc"
          }
        },
        {
          "sort": {
            "order": "desc"
          }
        },
        {
          "publish": {
            "order": "desc"
          }
        },
        {
          "createdTime": {
            "order": "desc"
          }
        }
      ]
    }
  }
}

复制代码

调用

GET general_content/_search/template
{
  "id": "content_search_template_v1",
  "params": {
    "platformId": "xxx",
    "typeCode":"xxx",
    "projectCode":"xxx",
    "publish":"xxx",
    "query": "xxx",
    "size": 10,
    "from": 0
  }
}
复制代码

哎吆吆 。可以。完全可以

这样就不需要那么一坨代码了。完全减轻了代码

使用template的好处

  • 避免在多个地方重复代码
  • 更容易测试和执行您的查询
  • 在应用程序间共享查询
  • 允许用户只执行一些预定义的查询
  • 将搜索逻辑与应用程序逻辑分离

问题

我又发现一个问题。我如果字段为null的适合 。不搜索这个字段怎么样办呢?

又发现了这篇文章:elasticstack.blog.csdn.net/article/det…

条件判断 在 Mustache 语言中,它没有 if/else 这样的判断,但是你可以定 section 来跳过它如果那个变量是 false 还是没有被定义:

{{#param1}}
    "This section is skipped if param1 is null or false"
{{/param1}}
复制代码

具体可以看看上面说的文章。这里不再展示

总结

使用search template 确实很好。搜索模板 可以修改。后期只需要动态配置上模板名称就好了。简单方便。

新手一枚,玩的开心。

Guess you like

Origin juejin.im/post/7032219160126226463