diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java index 8c8dfd3dbb..78236f0f0f 100644 --- a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java +++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java @@ -30,7 +30,9 @@ import static org.apache.jackrabbit.JcrConstants.JCR_DATA; import static org.apache.jackrabbit.JcrConstants.NT_FILE; import static org.apache.jackrabbit.oak.api.QueryEngine.NO_BINDINGS; import static org.apache.jackrabbit.oak.api.QueryEngine.NO_MAPPINGS; +import static org.apache.jackrabbit.oak.api.Type.BOOLEAN; import static org.apache.jackrabbit.oak.api.Type.NAMES; +import static org.apache.jackrabbit.oak.api.Type.STRING; import static org.apache.jackrabbit.oak.api.Type.STRINGS; import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME; import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.DECLARING_NODE_TYPES; @@ -74,8 +76,11 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Collections; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -115,6 +120,7 @@ import org.apache.jackrabbit.oak.plugins.index.nodetype.NodeTypeIndexProvider; import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider; import org.apache.jackrabbit.oak.plugins.memory.ArrayBasedBlob; import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore; +import org.apache.jackrabbit.oak.plugins.memory.MultiStringPropertyState; import org.apache.jackrabbit.oak.plugins.memory.PropertyStates; import org.apache.jackrabbit.oak.plugins.nodetype.TypeEditorProvider; import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent; @@ -2316,6 +2322,60 @@ public class LucenePropertyIndexTest extends AbstractQueryTest { } @Test + public void facetsInMultipleRoots() throws Exception { + // OAK-7109 + Tree luceneIndex = createFullTextIndex(root.getTree("/"), "lucene"); + Tree ntBaseProperties = luceneIndex + .getChild(LuceneIndexConstants.INDEX_RULES) + .getChild("nt:base") + .getChild(LuceneIndexConstants.PROP_NODE); + ntBaseProperties.setOrderableChildren(true); + + Tree simpleTags = ntBaseProperties.addChild("simpleTags"); + simpleTags.setProperty("facets", true, BOOLEAN); + simpleTags.setProperty("name", "simple/tags", STRING); + simpleTags.setProperty("propertyIndex", true, BOOLEAN); + simpleTags.setProperty("stored", true, BOOLEAN); + simpleTags.orderBefore("allProps"); + + root.commit(); + + final List names = new ArrayList<>(2); + // create a document with a simple/tags property in /content1 + Tree node1 = root.getTree("/").addChild("content1").addChild("test").addChild("foo"); + Tree node1Simple = node1.addChild("simple"); + node1.setProperty("text", "lorem ipsum"); + node1Simple.setProperty(MultiStringPropertyState.stringProperty("tags", Arrays.asList("tag1", "tag2"))); + names.add(node1.getPath()); + // now create a document without simple/tags property in content2 + Tree node2 = root.getTree("/").addChild("content2").addChild("test").addChild("bar"); + node2.setProperty("text", "lorem ipsum"); + Tree node2Simple = node2.addChild("simple"); + node2Simple.setProperty(MultiStringPropertyState.stringProperty("tags", Arrays.asList("tag1", "tag2"))); + names.add(node2.getPath()); + // now create a document without simple/tags property in content3 + Tree node3 = root.getTree("/").addChild("content3").addChild("test").addChild("bar"); + node3.setProperty("text", "lorem ipsum"); + Tree node3Simple = node3.addChild("simple"); + node3Simple.setProperty(MultiStringPropertyState.stringProperty("tags", Arrays.asList("tag1", "tag2"))); + + root.commit(); + // then query only for /content1 and /content2 + String query = "select [rep:facet(simple/tags)] from [nt:base] as a where contains(a.[*], 'ipsum') and " + + "(isdescendantnode(a,'/content1') or isdescendantnode(a,'/content2'))"; + assertQuery(query, names); + + Iterator results = executeQuery(query, SQL2, Collections.emptyMap()).getRows().iterator(); + assertTrue(results.hasNext()); + ResultRow firstRow = results.next(); + PropertyValue facets = firstRow.getValue("rep:facet(simple/tags)"); + assertNotNull(facets); + // our result set is 2 results long, so as all of the documents have the same tags we assume the count of both dimensions is 2 + assertEquals("{\"tag1\":2,\"tag2\":2}", facets.getValue(STRING)); + + } + + @Test public void longRepExcerpt() throws Exception { Tree luceneIndex = createFullTextIndex(root.getTree("/"), "lucene");