You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ca...@apache.org on 2015/12/03 15:05:04 UTC
svn commit: r1717768 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/query/
oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/
oak-doc/src/site/markdown/query/
oak-lucene/src/main/java/org/apache/jackrabbit/oak/plu...
Author: catholicon
Date: Thu Dec 3 14:05:04 2015
New Revision: 1717768
URL: http://svn.apache.org/viewvc?rev=1717768&view=rev
Log:
OAK-3352 Expose Lucene search score explanation
Use oak:scoreExplanation to show explanation of score as calculated by lucene. Filter is parsed in the same way as for rep:excerpt()
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
jackrabbit/oak/trunk/oak-doc/src/site/markdown/query/lucene.md
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java?rev=1717768&r1=1717767&r2=1717768&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java Thu Dec 3 14:05:04 2015
@@ -119,6 +119,11 @@ public class QueryImpl implements Query
public static final String REP_EXCERPT = "rep:excerpt";
/**
+ * The "oak:explainScore" pseudo-property.
+ */
+ public static final String OAK_SCORE_EXPLANATION = "oak:scoreExplanation";
+
+ /**
* The "rep:spellcheck" pseudo-property.
*/
public static final String REP_SPELLCHECK = "rep:spellcheck()";
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java?rev=1717768&r1=1717767&r2=1717768&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java Thu Dec 3 14:05:04 2015
@@ -661,6 +661,8 @@ public class SelectorImpl extends Source
result = currentRow.getValue(QueryImpl.JCR_SCORE);
} else if (oakPropertyName.equals(QueryImpl.REP_EXCERPT)) {
result = currentRow.getValue(QueryImpl.REP_EXCERPT);
+ } else if (oakPropertyName.equals(QueryImpl.OAK_SCORE_EXPLANATION)) {
+ result = currentRow.getValue(QueryImpl.OAK_SCORE_EXPLANATION);
} else if (oakPropertyName.equals(QueryImpl.REP_SPELLCHECK)) {
result = currentRow.getValue(QueryImpl.REP_SPELLCHECK);
} else if (oakPropertyName.equals(QueryImpl.REP_SUGGEST)) {
Modified: jackrabbit/oak/trunk/oak-doc/src/site/markdown/query/lucene.md
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/query/lucene.md?rev=1717768&r1=1717767&r2=1717768&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/query/lucene.md (original)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/query/lucene.md Thu Dec 3 14:05:04 2015
@@ -1008,6 +1008,16 @@ Since Oak 1.3.11, the each suggestion wo
- useInSpellcheck = true
```
+
+#### Score Explanation
+
+`@since Oak 1.3.12`
+
+Lucene supports [explanation of scores][score-explanation] which can be selected in a query using a virtual column `oak:scoreExplanation`.
+e.g. `select [oak:scoreExplanation], * from [nt:base] where foo='bar'`
+
+_Note that showing explanation score is expensive. So, this feature should be used for debug purposes only_.
+
### Design Considerations
Lucene index provides quite a few features to meet various query requirements.
@@ -1432,4 +1442,5 @@ such fields
[tika-download]: https://tika.apache.org/download.html
[oak-run-tika]: https://github.com/apache/jackrabbit-oak/tree/trunk/oak-run#tika
[jcr-contains]: http://www.day.com/specs/jcr/1.0/6.6.5.2_jcr_contains_Function.html
-[boost-faq]: https://wiki.apache.org/lucene-java/LuceneFAQ#How_do_I_make_sure_that_a_match_in_a_document_title_has_greater_weight_than_a_match_in_a_document_body.3F
\ No newline at end of file
+[boost-faq]: https://wiki.apache.org/lucene-java/LuceneFAQ#How_do_I_make_sure_that_a_match_in_a_document_title_has_greater_weight_than_a_match_in_a_document_body.3F
+[score-explanation]: https://lucene.apache.org/core/4_6_0/core/org/apache/lucene/search/IndexSearcher.html#explain%28org.apache.lucene.search.Query,%20int%29
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java?rev=1717768&r1=1717767&r2=1717768&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java Thu Dec 3 14:05:04 2015
@@ -299,7 +299,8 @@ public class LucenePropertyIndex impleme
return endOfData();
}
- private LuceneResultRow convertToRow(ScoreDoc doc, IndexSearcher searcher, String excerpt) throws IOException {
+ private LuceneResultRow convertToRow(ScoreDoc doc, IndexSearcher searcher, String excerpt,
+ String explanation) throws IOException {
IndexReader reader = searcher.getIndexReader();
//TODO Look into usage of field cache for retrieving the path
//instead of reading via reader if no of docs in index are limited
@@ -328,7 +329,7 @@ public class LucenePropertyIndex impleme
}
LOG.trace("Matched path {}", path);
- return new LuceneResultRow(path, doc.score, excerpt);
+ return new LuceneResultRow(path, doc.score, excerpt, explanation);
}
return null;
}
@@ -382,14 +383,22 @@ public class LucenePropertyIndex impleme
PERF_LOGGER.end(start, -1, "{} ...", docs.scoreDocs.length);
nextBatchSize = (int) Math.min(nextBatchSize * 2L, 100000);
- boolean addExcerpt = filter.getQueryStatement() != null && filter.getQueryStatement().contains(QueryImpl.REP_EXCERPT);
+ String queryStatement = filter.getQueryStatement();
+ boolean addExcerpt = queryStatement != null && queryStatement.contains(QueryImpl.REP_EXCERPT);
+ boolean addExplain = queryStatement != null && queryStatement.contains(QueryImpl.OAK_SCORE_EXPLANATION);
+
for (ScoreDoc doc : docs.scoreDocs) {
String excerpt = null;
if (addExcerpt) {
excerpt = getExcerpt(indexNode, searcher, query, doc);
}
- LuceneResultRow row = convertToRow(doc, searcher, excerpt);
+ String explanation = null;
+ if (addExplain) {
+ explanation = searcher.explain(query, doc.doc).toString();
+ }
+
+ LuceneResultRow row = convertToRow(doc, searcher, excerpt, explanation);
if (row != null) {
queue.add(row);
}
@@ -1324,8 +1333,10 @@ public class LucenePropertyIndex impleme
final String suggestion;
final boolean isVirutal;
final String excerpt;
+ final String explanation;
- LuceneResultRow(String path, double score, String excerpt) {
+ LuceneResultRow(String path, double score, String excerpt, String explanation) {
+ this.explanation = explanation;
this.excerpt = excerpt;
this.isVirutal = false;
this.path = path;
@@ -1339,6 +1350,7 @@ public class LucenePropertyIndex impleme
this.score = weight;
this.suggestion = suggestion;
this.excerpt = null;
+ this.explanation = null;
}
LuceneResultRow(String suggestion) {
@@ -1428,6 +1440,9 @@ public class LucenePropertyIndex impleme
if (QueryImpl.REP_SPELLCHECK.equals(columnName) || QueryImpl.REP_SUGGEST.equals(columnName)) {
return PropertyValues.newString(currentRow.suggestion);
}
+ if (QueryImpl.OAK_SCORE_EXPLANATION.equals(columnName)) {
+ return PropertyValues.newString(currentRow.explanation);
+ }
if (QueryImpl.REP_EXCERPT.equals(columnName)) {
return PropertyValues.newString(currentRow.excerpt);
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java?rev=1717768&r1=1717767&r2=1717768&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java Thu Dec 3 14:05:04 2015
@@ -432,6 +432,22 @@ public class LucenePropertyIndexTest ext
assertQuery("select [jcr:path] from [nt:base] where propa is not null", asList("/test/a", "/test/b"));
}
+ @Test
+ public void explainScoreTest() throws Exception {
+ Tree idx = createIndex("test1", of("propa"));
+ idx.addChild(PROP_NODE).addChild("propa");
+ root.commit();
+
+ Tree test = root.getTree("/").addChild("test");
+ test.addChild("a").setProperty("propa", "a");
+ root.commit();
+
+ String query = "select [oak:scoreExplanation] from [nt:base] where propa='a'";
+ List<String> result = executeQuery(query, SQL2, false, false);
+ assertEquals(1, result.size());
+ assertTrue(result.get(0).contains("(MATCH)"));
+ }
+
//OAK-2568
@Test
public void multiValueAnd() throws Exception{