Индекс Lucene с несколькими полями одинаковой природы - PullRequest
7 голосов
/ 09 марта 2010

Каждый документ Lucene - это рецепт, и в каждом из этих рецептов есть ингредиенты.

Я работаю над тем, чтобы найти ингредиенты и получить результат, который говорит о том, что два ингредиента соответствуют четырем из четырех.(например)

Так как я могу добавить ингредиенты в документ?В solr я могу просто создать несколько полей и сохранить их все, возможно, я делаю что-то не так, потому что он сохраняет только один ингредиент.

Также это относится к полю типа «теги».

ps Я использую Zend Framework для этого, если это вообще имеет значение.

Ответы [ 2 ]

13 голосов
/ 10 марта 2010

Документы Lucene поддерживают добавление нескольких полей с одним и тем же именем. то есть вы можете повторно звонить:

document.add(new Field("name"), value) 

Так ты должен был сделать:

# (pseudo-code) 
document1.add(new Field("ingredient"), "vanilla") 
document1.add(new Field("ingredient"), "strawberry") 
index.add(document)

# And then search for
index.search("ingredient", "vanilla" && "strawberry")

Вы получите обратно документ1. Но если вы ищете:

index.search("ingredient", "vanilla" && "apple")

Ты не вернешься document1 .

Если вы искали:

index.search("ingredient", "vanilla" || "apple")

Вы также получите обратно document1 .

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

Также обратите внимание, что по умолчанию PositionIncrementGap для полей с тем же именем, которые добавляются в документ, равно 0.

Это означает, что если вы добавили:

   document1.add(new Field("ingredient"), "chocolate") 
   document1.add(new Field("ingredient"), "orange") 

тогда это будет рассматриваться как отдельный ингредиент, называемый "шоколадный апельсин", который может соответствовать:

index.search("ingredient", "chocolate orange")

Вы можете избежать установки этого значения для PositionIncrementGap> 1, что приведет к:

0 соответствует:

index.search("ingredient", "chocolate orange")

и 1 соответствует:

index.search("ingredient", "chocolate" &&  "orange")
0 голосов
/ 10 марта 2010

Здесь я вижу два возможных подхода:

  1. Денормализация ваших данных - создайте отдельный документ для каждого ингредиента в рецепте, давая всем документам для рецепта общий идентификатор рецепта. Затем во время поиска агрегируйте все совпадения идентификатора рецепта. Немного некрасиво.
  2. Объедините все свои ингредиенты в общее поле и внесите в индекс «Текст». Затем ищите ингредиенты, используя логический запрос с «ИЛИ» (это называется «должен» в терминах Java Lucene, я не знаю эквивалент PHP).

Я предлагаю вам попробовать второй подход и посмотреть, поможет ли он.

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