There is a ready elastic index used for autocompletions. I figured out how to filter by one word consisting of letters, but I can’t figure out how to make a search so that you can do a word search with spaces. For example, I can find in the names field for the request "Ivanov" a record like "Ivan Ivan Ivanovich," but if I ask the search for "Ivan Ivanov," then nothing will return. A piece of code:

SearchSourceBuilder search = SearchSourceBuilder.searchSource(); BoolQueryBuilder query = new BoolQueryBuilder(); String value = "Иванов Иван"; //строка которая ищется в индексе query.must(QueryBuilders.regexpQuery("names",".*" + value.replaceAll("([+\\-!\\(\\){}\\[\\]^\"~*?:\\\\]|[&\\|]{2})", "\\\\$1") + ".*")); search.query(query); 

    1 answer 1

    If you use the standard analyzer for the names field, it breaks the phrase into three tokens "Ivanov", "Ivan", "Ivanovich". And your query looks like this:

     { "regexp": { "names": ".*Иванов Иван.*" }} 

    Naturally, no matches will be found with any token. I see two solutions to the problem:

    1. Fix mapping by adding a virtual field names.raw to search. It will have one token "Ivanov Ivan Ivanovich", since not used analyzer.

       { "mappings": { "names": { "type": "string", "fields": { "raw": { "type": "string", "index": "not_analyzed" } } } } } 

    Search by this virtual field.

     query.must(QueryBuilders.regexpQuery("names.raw",".*" + value.replaceAll("([+\\-!\\(\\){}\\[\\]^\"~*?:\\\\]|[&\\|]{2})", "\\\\$1") + ".*")); 
    1. No change mapping. Break the keyword as a standard analyzer does. In the simplest case, the breakdown into phrases, separated by a space. And do a more complex search for each such phrase.

       { "query": { "bool": { "should": { "regexp": { "names": ".*Иванов.*" }}, "should": { "regexp": { "names": ".*Иван.*" }} } } } 

    Or use must instead of should, depending on what kind of logic you need.

    Please note that the search logic is slightly different in these two options.

    • Fine. +1 your answer. I wanted to write the answer, but the knowledge of the elastic is not enough for such a complete answer as you have. - ReinRaus