Кажется, нет встроенного алгоритма.Я полагаю, что есть три способа сделать это:
a) Запустите запрос MoreLikeThis для одного из документов.Переберите результаты, проверьте идентификатор документа и получите оценку.Может быть, не очень, вам может понадобиться вернуть много документов для того, который вы хотите быть среди возвращенных.
b) Сходство косинусов: ответы по ссылке, предоставленной Микосом в его комментарии, объясняют, как сходство косинусовможно рассчитать для двух документов.
в) Вычислите свой собственный показатель сходства Lucene.Счет Lucene добавляет несколько факторов к косинусному сходству (http://lucene.apache.org/core/4_2_0/core/org/apache/lucene/search/similarities/TFIDFSimilarity.html).
. Вы можете использовать
DefaultSimilarity ds = new DefaultSimilarity();
SimScorer scorer = ds.simScorer(stats , arc);
scorer.score(otherDocId, freq);
. Вы можете получить параметры, например, через
AtomicReaderContext arc = IndexReader.leaves().get(0);
SimWeight stats = ds.computeWeight(1, collectionStats, termStats);
stats.normalize(1, 1);
, гдев свою очередь, вы можете получить термин stats, используя TermVector для первого из ваших двух документов, и ваш IndexReader для сбора статистики. Чтобы получить параметр freq
, используйте
DocsEnum docsEnum = MultiFields.getTermDocsEnum(reader, null, field, term);
, итерируйте документы довы находите идентификатор документа вашего первого документа и делаете
freq = docsEnum.freq();
Обратите внимание, что вам нужно вызывать «scorer.score» для каждого термина (или каждого термина, который вы хотите рассмотреть) в вашем первом документе, иСуммируйте результаты.
В конце, чтобы умножить параметры «queryNorm» и «координировать», вы можете использовать
//sumWeights was computed while iterating over the first termvector
//in the main loop by summing up "stats.getValueForNormalization();"
float queryNorm = ds.queryNorm(sumWeights);
//thisTV and otherTV are termvectors for the two documents.
//overlap can be easily calculated
float coord = ds.coord(overlap, (int) Math.min(thisTV.size(), otherTV.size()));
return coord * queryNorm * score;
Так что это способ, который должен работать.это не элегантно и из-за сложности получения частот терминов (итерирование по DocsEnum для каждого термина), это также не очень эффективно. Я все еще надеюсь, что что-то из этого кому-то поможет:)