From 3c60a00b694cb9d648e612b373fc294671fe1b8c Mon Sep 17 00:00:00 2001 From: Doron Cohen Date: Wed, 25 Apr 2007 21:10:43 +0000 Subject: [PATCH] LUCENE-789: fix MultiSearcher to not ignore its custom similarity. git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@532487 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 5 +++ .../apache/lucene/search/MultiSearcher.java | 7 ++-- .../lucene/search/TestMultiSearcher.java | 38 +++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6c28b4e7df6..0bb9ffe099d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -105,6 +105,11 @@ Bug fixes 13. LUCENE-736: Sloppy phrase query with repeating terms matches wrong docs. For example query "B C B"~2 matches the doc "A B C D E". (Doron Cohen) +14. LUCENE-789: Fixed: custom similarity is ignored when using MultiSearcher (problem reported + by Alexey Lef). Now the similarity applied by MultiSearcer.setSimilarity(sim) is being used. + Note that as before this fix, creating a multiSearcher from Searchers for whom custom similarity + was set has no effect - it is masked by the similarity of the MultiSearcher. This is as + designed, because MultiSearcher operates on Searchables (not Searchers). (Doron Cohen) New features diff --git a/src/java/org/apache/lucene/search/MultiSearcher.java b/src/java/org/apache/lucene/search/MultiSearcher.java index 3ef5631fd9e..aa72b077d14 100644 --- a/src/java/org/apache/lucene/search/MultiSearcher.java +++ b/src/java/org/apache/lucene/search/MultiSearcher.java @@ -43,9 +43,10 @@ public class MultiSearcher extends Searcher { private Map dfMap; // Map from Terms to corresponding doc freqs private int maxDoc; // document count - public CachedDfSource(Map dfMap, int maxDoc) { + public CachedDfSource(Map dfMap, int maxDoc, Similarity similarity) { this.dfMap = dfMap; this.maxDoc = maxDoc; + setSimilarity(similarity); } public int docFreq(Term term) { @@ -106,7 +107,7 @@ public class MultiSearcher extends Searcher { public TopFieldDocs search(Weight weight,Filter filter,int n,Sort sort) { throw new UnsupportedOperationException(); } - }; + } private Searchable[] searchables; @@ -320,7 +321,7 @@ public class MultiSearcher extends Searcher { // step4 int numDocs = maxDoc(); - CachedDfSource cacheSim = new CachedDfSource(dfMap, numDocs); + CachedDfSource cacheSim = new CachedDfSource(dfMap, numDocs, getSimilarity()); return rewrittenQuery.weight(cacheSim); } diff --git a/src/test/org/apache/lucene/search/TestMultiSearcher.java b/src/test/org/apache/lucene/search/TestMultiSearcher.java index 4a6d047ddf2..514ad4f77c2 100644 --- a/src/test/org/apache/lucene/search/TestMultiSearcher.java +++ b/src/test/org/apache/lucene/search/TestMultiSearcher.java @@ -354,4 +354,42 @@ public class TestMultiSearcher extends TestCase ramDirectory1.close(); ramDirectory2.close(); } + + /** + * test that custom similarity is in effect when using MultiSearcher (LUCENE-789). + * @throws IOException + */ + public void testCustomSimilarity () throws IOException { + RAMDirectory dir = new RAMDirectory(); + initIndex(dir, 10, true, "x"); // documents with two tokens "doc0" and "x", "doc1" and x, etc... + IndexSearcher srchr = new IndexSearcher(dir); + MultiSearcher msrchr = getMultiSearcherInstance(new Searcher[]{srchr}); + + Similarity customSimilarity = new DefaultSimilarity() { + // overide all + public float idf(int docFreq, int numDocs) { return 100.0f; } + public float coord(int overlap, int maxOverlap) { return 1.0f; } + public float lengthNorm(String fieldName, int numTokens) { return 1.0f; } + public float queryNorm(float sumOfSquaredWeights) { return 1.0f; } + public float sloppyFreq(int distance) { return 1.0f; } + public float tf(float freq) { return 1.0f; } + }; + + srchr.setSimilarity(customSimilarity); + msrchr.setSimilarity(customSimilarity); + + Query query=new TermQuery(new Term("contents", "doc0")); + + // Get a score from IndexSearcher + TopDocs topDocs = srchr.search(query, null, 1); + float score1 = topDocs.getMaxScore(); + + // Get the score from MultiSearcher + topDocs = msrchr.search(query, null, 1); + float scoreN = topDocs.getMaxScore(); + + // The scores from the IndexSearcher and Multisearcher should be the same + // if the same similarity is used. + assertEquals("MultiSearcher score must be equal to single esrcher score!", score1, scoreN, 1e-6); + } }