Как написать следующий elasti c -search подстановочный запрос при весенней загрузке? - PullRequest
0 голосов
/ 27 апреля 2020

База данных: Elasticsearch

Имя поля: "tag"

Тип данных: String

Вопрос: Как выполнить поиск в поле tag с подстановочным знаком ?

Я попробовал следующее (в Кибане):

Запрос пользователя: { "tag" : [ "Attendance", "Employee" ] }

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

Это сработало успешно, но я не представляю, как Выполните то же самое в весенней загрузке.

Я работал со следующим:

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

Но это только для одного поля, у меня есть требование для поля Dynami c, где пользователь ввод должен быть разным по размеру и значению.

Может кто-нибудь, пожалуйста, наставить меня?

1 Ответ

1 голос
/ 27 апреля 2020

Вы можете использовать что-то вроде этого:

Запрос клиента Highlevel уровня Rest:

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, который я автоматически связал в своем классе следующим образом:

@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
  }
}

Я проверил, создав индекс с тем же отображением, которое вы указали:

Отображение

"mappings": {
            "properties": {
                "tag": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                }
            }
        }

Индексированные документы:

Doc1

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

Doc2

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

Doc3

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

Doc4

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

И когда я выполняю поиск по оставшемуся запросу, я получаю следующий ответ:

Ответ

"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);
...