Каков наилучший способ настроить Spring JPA для обработки поиска элементов по тегам? - PullRequest
0 голосов
/ 16 февраля 2020

Я пытаюсь настроить систему поиска для базы данных, в которой каждый элемент (код) в одной таблице имеет теги, сопоставленные отношением «многие ко многим». Я пытаюсь написать контроллер, «поиск», где я могу искать набор тегов, которые в основном действуют как ключевые слова, давая мне список элементов, где все элементы имеют указанные теги. Моя текущая функция невероятно наивна, в основном она состоит из извлечения всех кодов, которые отображаются как теги, затем добавления этих наборов, затем сортировки кодов по тому, сколько раз теги для каждого кода были найдены в строке запроса.

  public List<Code> naiveSearch(String queryText) {
    String[] tagMatchers = queryText.split(" ");
    Set<Code> retained = new HashSet<>();
    for (int i = 0; i < Math.min(tagMatchers.length, 4); i++) {
      tagRepository.findAllByValueContaining(tagMatchers[i]).ifPresent((tags) -> {
        tags.forEach(tag -> {
              retained.addAll(tag.getCodes());
            }
        );
      });
    }
    SortedMap<Integer, List<Code>> matches = new TreeMap<>();
    List<Code> c;
    for (Code code : retained) {
      int sum = 0;
      for (String tagMatcher : tagMatchers) {
        for (Tag tag : code.getTags()) {
          if (tag.getValue().contains(tagMatcher)) {
            sum += 1;
          }
        }
      }
      c = matches.getOrDefault(sum, new ArrayList<>());
      c.add(code);
      matches.put(sum, c);
    }
    c = new ArrayList<>();
    matches.values().forEach(c::addAll);
    Collections.reverse(c);
    return c;

  }

Это довольно медленно и накладные расходы недопустимы. Мой предыдущий трюк заключался в основном в поиске описания для каждого кода в CRUDrepository


public interface CodeRepository extends CrudRepository<Code, Long> {

  Optional<Code> findByCode(String codeId);
  Optional<Iterable<Code>> findAllByDescriptionContaining(String query);

}

Однако это хрупко, поскольку порядок тегов, содержащих факторы, определяет, будет ли найден результат. например. Я хочу "высокий ... собака" == "собака ... высокий"

1 Ответ

0 голосов
/ 22 февраля 2020

Итак, я вернулся через несколько дней с тем, как я на самом деле решил эту проблему. Я использовал встроенную библиотеку поиска hibernate , которая имеет очень простую реализацию весной. Просто вставьте необходимые координаты maven в POM. xml и он готов к работе.

Сначала я удалил множество кодов тегов <-> и просто соединил все мои теги в строковое поле. Затем я добавил @Field в поле тегов, а затем написал базовый c метод поиска. Метод, который я написал, был очень простой функцией поиска, которая брала набор «ключевых слов» или тегов, а затем выполняла логический поиск на основе нечетких терминов для индексированных тегов для каждого кода. Пока это довольно хорошо. Моя база данных довольно мала (100 КБ), поэтому я не уверен, как это будет масштабироваться, но в настоящее время каждый поиск возвращает примерно 20-50 мс, что достаточно быстро для моих целей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...