Увеличение многозначных полей - PullRequest
4 голосов
/ 29 октября 2009

У меня есть набор документов, содержащий отмеченные объекты, которые я хотел бы проиндексировать. Наша структура данных выглядит так:

Document
  ID
  Text
  List<RelatedScore>

RelatedScore
  ID
  Score

Моей первой мыслью было добавление каждого RelatedScore в качестве многозначного поля с использованием свойства Boost поля для изменения значения конкретной оценки при поиске.

foreach (var relatedScore in document.RelatedScores) {
  var field = new Field("RelatedScore", relatedScore.ID,
                        Field.Store.YES, Field.Index.UN_TOKENIZED);
  field.SetBoost(relatedScore.Score);
  luceneDoc.Add(field);
}

Однако, похоже, что вычисленная «норма» применяется ко всему мультиполю - все значения RelatedScore для документа в итоге получат одинаковую оценку.

Есть ли в Lucene механизм, позволяющий использовать эту функцию? Я бы предпочел не создавать другой индекс только для учета этого - такое ощущение, что должен быть способ использовать один индекс. Если нет средств для достижения этой цели, несколько идей, которые мы должны компенсировать:

  1. Вставка элементов поля с несколькими значениями в порядке убывания значения. Затем каким-то образом добавьте позиционно-ориентированный анализ, чтобы присвоить более высокий импульс / оценку первым предметам в поле.
  2. Добавить высокий балл оценки несколько раз в поле. Таким образом, RelatedScore со счетом == 1 можно добавить три раза, а RelatedScore со счетом ==. 3 можно добавить только один раз.

Оба из них приведут к потере точности поиска в этих полях, да, но они могут быть достаточно хорошими. Есть мысли по этому поводу?

Ответы [ 2 ]

3 голосов
/ 30 октября 2009

Это пример использования полезных нагрузок. Я не уверен, что это доступно в Lucene.NET, так как я использовал только версию Java.

Еще один хакерский способ сделать это, если абсолютные значения баллов не так важны, - это дискретизировать их (поместить их в сегменты в зависимости от значения) и создать поле для каждого сегмента. Поэтому, если у вас есть оценки в диапазоне от 1 до 100, создайте, скажем, 10 групп с именами RelatedScore0_10, RelatedScore10_20 и т. Д., И для любого документа, в котором есть RelatedScore в этом сегменте, добавьте значение «true» в это поле. Затем для каждого поиска, который выполняется Tack по запросу OR, как:

(RelatedScore0_10:true^1 RelatedScore10_20:true^2 ...)

Хорошая вещь об этом заключается в том, что вы можете настроить значения усиления для каждого из ваших блоков на лету. В противном случае вам нужно будет переиндексировать, чтобы изменить значения нормы поля (повышения) для каждого поля.

0 голосов
/ 02 ноября 2009

Если вы используете Lucene.Net, возможно, у вас еще нет функциональности полезной нагрузки. Что вы можете сделать, это конвертировать 0-100 баллов релевантности в интервал от 1 до 10 (целочисленное деление на 10), а затем добавить каждое индексированное значение столько раз (но только сохранить значение один раз). Затем, если вы будете искать это поле, встроенная оценка lucene будет учитывать частоту индексированного поля (оно будет проиндексировано 1-10 раз в зависимости от релевантности). Поэтому результаты могут быть отсортированы по релевантности переменной.

foreach (var relatedScore in document.RelatedScores) {
  // get bucket for relevance...
  int bucket=relatedScore.Score / 10;

  var field = new Field("RelatedScore", relatedScore.ID,
                        Field.Store.YES, Field.Index.UN_TOKENIZED);
  luceneDoc.Add(field);
  // add more instances of field but only store the first one above...
  for(int i=0;i<bucket;i++)
  {
    luceneDoc.Add(new Field("RelatedScore", relatedScore.ID,
                        Field.Store.NO, Field.Index.UN_TOKENIZED));
  }
} 
...