ElasticSearch 7.6.3 Java HighLevel Rest Client: автоматическое предложение по нескольким полям - как реализовать - PullRequest
1 голос
/ 25 февраля 2020

У нас есть индекс со следующими полями, и существует требование предоставить пользователю автоматическое предложение путем поиска данных по всем полям сопоставления текста и ключевых слов в индексе

{


"settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1,
    "analysis": {
      "filter": {
        "autocomplete_filter": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 20
        }
      },
     }
  },

  "mappings": {
    "properties": {
      "id": {
        "type": "text"
      },
      "title": {
        "type": "text"
      },
      "date": {
        "type": "date",
        "format": "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
      },
      "subject": {
        "type": "text"
      },
      "title_suggest": {
            "type": "completion",
            "analyzer": "simple",
            "preserve_separators": true,
            "preserve_position_increments": true,
            "max_input_length": 50
        },
        "subject_suggest": {
            "type": "completion",
            "analyzer": "simple",
            "preserve_separators": true,
            "preserve_position_increments": true,
            "max_input_length": 50

        }
      "fieldOr": {
        "type": "text"
      },
      "fieldsTa": {
        "type": "text"
      },
      "notes": {
        "type": "text"
      },
      "fileDocs": {
        "type": "nested",
        "properties": {
          "fileName": {
            "type": "text",
            "analyzer": "autocomplete", 
            "search_analyzer": "standard"
          },
          "fileContent": {
            "type": "text",
            "analyzer": "autocomplete", 
            "search_analyzer": "standard" 
          },
          "docType": {
            "type": "keyword"
          },
          "opinionId": {
            "type": "integer"
          }
        }
      },   
      "fileMeta": {
        "type": "nested",
        "properties": {
          "url": {
            "type": "text"
          },
          "name": {
            "type": "text"
          }
        }
      }
    }
  }
}

Я пытался Завершение Предложите, но оно работает с 1 полями. Я создал 2 поля с * -suggest в индексе и попытался создать Suggest, используя завершениеSuggest

SuggestBuilders.completionSuggestion("my_index_suggest").text(input);

Но оно поддерживает только 1 поле. Я использую ES 7.6.3 с Java HighLevel Rest Client, и он работает для 1 полей. Какие изменения мне нужно сделать, чтобы поддерживать несколько полей. Это возможно с помощью поиска JSON? Если да, то я могу создать json с помощью Xcontentbuilder и сделать автоматическое предложение?

Ответы [ 2 ]

1 голос
/ 21 марта 2020

В качестве иллюстрации я использую свое собственное отображение индекса, в котором есть только два поля name и address, и я буду делать запросы на автозаполнение, используя префикс для обоих полей, и вы можете добавить больше поля аналогично.

Отображение индекса

{
  "employee": {
    "mappings": {
      "properties": {
        "address": {
          "type": "text"
        },
        "name": {
          "type": "text"
        }
      }
    }
  }
}

Поисковый запрос с использованием высокоуровневого клиента Rest

 public SearchResponse autosuggestSearch() throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder qb = QueryBuilders.boolQuery();

        PrefixQueryBuilder namePQBuilder = QueryBuilders.prefixQuery("address", "usa");
        PrefixQueryBuilder addressPQBuilder = QueryBuilders.prefixQuery("address", "usa");
        qb.should(namePQBuilder);
        qb.should(addressPQBuilder); //Similarly add more fields prefix queries.
        sourceBuilder.query(qb);

        SearchRequest searchRequest = new SearchRequest("employee").source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println("Search JSON query \n" + searchRequest.source().toString()); //Generated ES search JSON.
        return searchResponse;
    }

Для этого примера сгенерированный поиск JSON

{
  "query": {
    "bool": {
      "should": [
        {
          "prefix": {
            "address": {
              "value": "usa",
              "boost": 1.0
            }
          }
        },
        {
          "prefix": {
            "address": {
              "value": "usa",
              "boost": 1.0
            }
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1.0
    }
  }
}
}
1 голос
/ 25 февраля 2020

Используйте copy_to и скопируйте все нужные поля в одно поле и выполните ваше предложение поверх него.

Пример из документации для copy_to:

PUT my_index
{
  "mappings": {
    "properties": {
      "first_name": {
        "type": "text",
        "copy_to": "full_name" 
      },
      "last_name": {
        "type": "text",
        "copy_to": "full_name" 
      },
      "full_name": {
        "type": "text"
      }
    }
  }
}
...