如何在 spring 引导中编写以下 elastic-search 通配符查询?

How to write following elastic-search wildcard query in spring boot?

数据库:Elasticsearch

字段名称:"tag"

数据类型:字符串

问题:如何在 tag 字段中使用通配符进行搜索?

我尝试了以下(在 Kibana 中):

用户请求:{ "tag" : [ "Attendance", "Employee" ] }

POST test/_search
{
    "query":{
        "bool" : {
          "should" : [
            {"wildcard":{"tag.keyword": "*Attendance*" }},
            {"wildcard":{"tag.keyword": "*Employee*" }}
          ]
        }
    }
}

这很成功,但我不知道如何在 spring 启动时执行相同的操作。

我与以下人员合作:

.should(wildcardQuery("tag.keyword", "Attendance"))

但这只是针对单个字段, 我需要一个动态字段,其中用户输入的大小和值应该不同。

有人可以指导我吗?

你可以使用这样的东西:

其余高级客户端查询:

SearchRequest searchRequest = new SearchRequest(<your-index-name>);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
 QueryBuilder query =  QueryBuilders.boolQuery().should(new WildcardQueryBuilder("tag.keyword", "*Attendance*"))
                    .should(new WildcardQueryBuilder("tag.keyword", "*Employee*"));
searchSourceBuilder.query(query);
searchRequest.source(searchSourceBuilder);

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

这里 client 是我在 class 中自动装配的 RestHighLevelClient bean,如下所示:

@Autowired
private RestHighLevelClient client;

我在配置 class 中将这个 bean 定义为:

@Bean(destroyMethod = "close")
public RestHighLevelClient client() {

        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http")));

        return client;

}

这将以这种形式构建查询:

查询

    {
  "bool" : {
    "should" : [
      {
        "wildcard" : {
          "tag.keyword" : {
            "wildcard" : "*Attendance*",
            "boost" : 1.0
          }
        }
      },
      {
        "wildcard" : {
          "tag.keyword" : {
            "wildcard" : "*Employee*",
            "boost" : 1.0
          }
        }
      }
    ],
    "adjust_pure_negative" : true,
    "boost" : 1.0
  }
}

我已经通过创建具有与您提到的相同映射的索引进行了测试:

索引的文档:

  "_source": {
            "tag": "Attendance1"
    }


    "_source": {
            "tag": "1Employee"
    }



      "_source": { "tag": "*Employee*" }


    { "tag" : [ "Attendance", "Employee" ] }

当我使用上面的 rest 查询进行搜索时,我得到了以下响应:

回应

"hits": [
        {
            "_index": "test",
            "_type": "_doc",
            "_id": "4",
            "_score": 2.0,
            "_source": {
                "tag": [
                    "Attendance",
                    "Employee"
                ]
            }
        },
        {
            "_index": "test",
            "_type": "_doc",
            "_id": "1",
            "_score": 1.0,
            "_source": {
                "tag": "Attendance1"
            }
        },
        {
            "_index": "test",
            "_type": "_doc",
            "_id": "2",
            "_score": 1.0,
            "_source": {
                "tag": "*Employee*"
            }
        },
        {
            "_index": "test",
            "_type": "_doc",
            "_id": "3",
            "_score": 1.0,
            "_source": {
                "tag": "1Employee"
            }
        }
    ]

不确定你问题的这一部分是什么意思:

I have requirement for dynamic field where user input should be different in size and value.

但是,我假设这意味着您可能会从用户那里获得不同的 tag 列表,并基于该列表创建查询。

你可以做这样的事情来达到同样的效果:

        // { "tag" : [ "Attendance", "Employee" ] } you can read this tag list though converter and pass it into list kind of data structure. Currently, I have created dummy list `tags` which has Attendance and Employee as items.
            List<String> tags = new ArrayList<>();
            tags.add("Attendance");
            tags.add("Employee");

            SearchRequest searchRequest = new SearchRequest(<your-index-name>);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            List<WildcardQueryBuilder> wildcards = new ArrayList<WildcardQueryBuilder>();

            for(String tag :  tags) {
                WildcardQueryBuilder wildcard =  new WildcardQueryBuilder("tag.keyword", "*" + tag + "*");
                wildcards.add(wildcard);

            }
            BoolQueryBuilder boolQuery = new BoolQueryBuilder();
            for(WildcardQueryBuilder wildcard : wildcards) {
                boolQuery.should(wildcard);
            }

            searchSourceBuilder.query(boolQuery);
            searchRequest.source(searchSourceBuilder);

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