0

数据库:弹性搜索

字段名称:“标签”

数据类型:字符串

问题:如何在tag带有通配符的字段中执行搜索?

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

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

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

这很成功,但我不知道如何在 Spring Boot 中执行相同的操作。

我与以下人员一起工作:

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

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

有人可以指导我吗?

4

1 回答 1

1

你可以使用这样的东西:

休息高级客户端查询:

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是我在课堂上自动装配的 RestHighLevelClient bean,如下所示:

@Autowired
private RestHighLevelClient client;

这个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 query 进行搜索时,我得到了以下响应:

回复

"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);
于 2020-04-27T14:04:16.217 回答