Расширение многозначных полей

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

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 с Score == 1 может быть добавлен три раза, а RelatedScore с Score ==. 3 может быть добавлен только один раз.

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


person James Kolpack    schedule 29.10.2009    source источник


Ответы (2)


Похоже, это вариант использования полезной нагрузки. Я не уверен, доступно ли это в Lucene.NET, поскольку я использовал только версию Java.

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

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

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

person bajafresh4life    schedule 30.10.2009
comment
Я смог использовать полезную нагрузку для хранения оценки и использовать ее через настраиваемый объект подобия. Как только я начал искать в этом направлении, я обнаружил, что Грант Ингерсолл недавно разместил статью именно на эту тему здесь: lucidimagination.com/blog/2009/08/05/ - person James Kolpack; 01.11.2009
comment
В настоящее время правильная ссылка - lucidworks.com/blog/refresh-getting-started- с полезными нагрузками - person user3159253; 16.11.2014

Если вы используете 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));
  }
} 
person Community    schedule 02.11.2009