springboot项目使用elasticsearch

springboot项目使用elasticsearch-rest-high-level-client接入elasticsearch,搜索功能实现

我的Mapping是

@Test
    public void creaetMapping() {
        PutMappingRequest putMappingRequest=new PutMappingRequest(ES_INDEX);
        try{
            XContentBuilder  xContentBuilder= JsonXContent.contentBuilder();
            xContentBuilder.startObject()
                    .startObject("properties")
                    .startObject("fileName")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("filePath")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("actionName")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("oldInfo")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("newInfo")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("actionUserName")
                    .field("type", "keyword")
                    .endObject()
                    .startObject("updateTime")
                    .field("type", "keyword")
                    //.field("analyzer", "ik_max_word")
                    .endObject()
                    .endObject().endObject();

            putMappingRequest.source(xContentBuilder);
            client.indices().putMapping(putMappingRequest,RequestOptions.DEFAULT);
        }catch (Exception e){
              e.printStackTrace();
        }
    }

存储的数据字段有

"sourceAsMap": {
                    "fileName": "文件名.1231233123--18.zip",
                    "oldInfo": "网盘/测试文件夹/埃尔文3331111111111234234/elasticsearch-analysis-ik-7.7.0.zip",
                    "filePath": "网盘/测试文件夹/埃尔文22224234/elasticsearch-analysis-ik-7.7.0.zip",
                    "newInfo": "网盘/测试文件夹/埃尔文12322222222234324/elasticsearch-analysis-ik-7.7.0.zip",
                    "actionUserName": "超级管理员",
                    "updateTime": 1615875335814
                },

我的搜索功能实现是:

   public SearchResponse search(SearchPo searchPo) throws IOException {
        System.out.print("搜索关键词:"+searchPo.getKeyword());


        MultiMatchQueryBuilder multiMatchQueryBuilder=QueryBuilders
                .multiMatchQuery(searchPo.getKeyword(),"fileName","actionUserName","actionName","filePath","newInfo","oldInfo");
        BoolQueryBuilder boolQueryBuilder=null;
        if(StringUtils.isNotEmpty(searchPo.getKeyword())){
            boolQueryBuilder = QueryBuilders.boolQuery()
                    .filter(multiMatchQueryBuilder);
        }

        //分页
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
                .query(boolQueryBuilder)
                .from(searchPo.pageNum)
                .size(searchPo.pageSize)
                .timeout(new TimeValue(60, TimeUnit.SECONDS));
        // SortOrder.DESC|SortOrder.ASC
        sourceBuilder.sort("updateTime",SortOrder.DESC);

        //查询
        SearchRequest searchRequest = new SearchRequest()
                .allowPartialSearchResults(true)
                .indices(ElFinderConstants.ELFINDER_EC_INDEX)
                .source(sourceBuilder);

        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

        return  response;
    }

我想实现关键词+分页+时间排序搜索。现在分页和时间排序都没有问题,但是关键字只能用某个字段的全部去搜才能搜到。我最终想实现输入关键词,只要在上面那几个字段里面出现过都可以搜到得到。

例如1:我想实现输入"管理员",就出现所有字段里面包含有"管理员"这三个字的结果。"超级管理员"或者“xxx管理员”都能匹配到。但是现在只有关键词和字段值一模一样才能匹配。我输入管理员,结果里面匹配不到超级管理员,只有输入超级管理员才能匹配到上面结果。

例如2:文件名的值是“文件名.1231233123--18.zip”,只能用完整的“文件名.1231233123--18.zip”作为搜索关键词才能搜索出来。时间上我想要只 输入“zip”就把相关的都搜到到。

也就是现在的搜索,实现的是字段等于关键词,我想要的是字段包含关键词就可以查询到。

最好是有完整的demo能够跑成功。网上我查了整整一天基本上都不行

 

es首先得加中文分词插件(好像叫什么ik分词),创建document的时候,还得加配置的,

具体就得百度了,这有点久了,不太记得具体是什么东西了

MultiMatchQueryBuilder multiMatchQueryBuilder=QueryBuilders.multiMatchQuery(searchPo.getKeyword(),"fileName","actionUserName","actionName","filePath","newInfo","oldInfo");
        BoolQueryBuilder boolQueryBuilder=null;
        if(StringUtils.isNotEmpty(searchPo.getKeyword())){
            boolQueryBuilder = QueryBuilders.boolQuery()
                    .filter(multiMatchQueryBuilder);
        }

应该是这一段有问题。 multiMatchQuery 类似与sql中的  aaa=xxx or bbb = xxx  你的使用场景应该是 关键字的匹配 拆分或者不拆分 的 类似的应该用 termQuery 跟wildcardQuery

elasticsearch不适合模糊查询