Skip to content
Permalink
Browse files
Merge pull request #518 from apache/OAK-9724
OAK-9724 Handle duplicate functions gracefully in indexing
  • Loading branch information
thomasmueller committed Mar 17, 2022
2 parents c3a6624 + 65a4f80 commit a0d1d8c8e511139299252a3ab4aef7d08c1a289c
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 5 deletions.
@@ -56,9 +56,15 @@ public class LuceneDocumentMaker extends FulltextDocumentMaker<Document> {
private static final Logger log = LoggerFactory.getLogger(LuceneDocumentMaker.class);

private static final String DYNAMIC_BOOST_SPLIT_REGEX = "[:/]";

// warn once every 10 seconds at most
private static final long DUPLICATE_WARNING_INTERVAL_MS = 10 * 1000;

private final FacetsConfigProvider facetsConfigProvider;
private final IndexAugmentorFactory augmentorFactory;

// when did we warn (static, as we construct new objects quite often)
private static long lastDuplicateWarning;

public LuceneDocumentMaker(IndexDefinition definition,
IndexDefinition.IndexingRule indexingRule,
@@ -283,8 +289,16 @@ protected boolean indexTypeOrderedFields(Document doc, String pname, int tag, Pr
}

if (f != null && includePropertyValue(property, 0, pd)) {
doc.add(f);
fieldAdded = true;
if (doc.getField(f.name()) == null) {
doc.add(f);
fieldAdded = true;
} else {
long now = System.currentTimeMillis();
if (now > lastDuplicateWarning + DUPLICATE_WARNING_INTERVAL_MS) {
log.warn("Duplicate value for ordered field {}; ignoring. Possibly duplicate index definition.", f.name());
lastDuplicateWarning = now;
}
}
}
} catch (Exception e) {
log.warn(
@@ -1117,6 +1117,56 @@ public void sameOrderableRelPropWithAndWithoutFunc_checkOrdering() throws Except

}

@Test
public void duplicateFunctionInIndex() throws Exception {
// Index def with same property - ordered - one with function and one without
Tree luceneIndex = createIndex("upper", Collections.<String>emptySet());
Tree prop = luceneIndex.addChild(FulltextIndexConstants.INDEX_RULES)
.addChild("nt:base")
.addChild(FulltextIndexConstants.PROP_NODE);
Tree upper1 = prop.addChild("upper1");
upper1.setProperty(FulltextIndexConstants.PROP_ORDERED,true);
upper1.setProperty(FulltextIndexConstants.PROP_FUNCTION, "fn:upper-case(jcr:content/n/@foo)");
Tree upper2 = prop.addChild("upper2");
upper2.setProperty(FulltextIndexConstants.PROP_ORDERED,true);
upper2.setProperty(FulltextIndexConstants.PROP_FUNCTION, "fn:upper-case(jcr:content/n/@foo)");
Tree upper3 = prop.addChild("upper3");
upper3.setProperty(FulltextIndexConstants.PROP_FUNCTION, "fn:upper-case(jcr:content/n/@foo)");
Tree upper4 = prop.addChild("upper4");
upper4.setProperty(FulltextIndexConstants.PROP_FUNCTION, "fn:upper-case(jcr:content/n/@foo)");

root.commit();

int i = 1;
// Create nodes that will be served by the index definition that follows
for (String node : asList("a", "c", "b", "e", "d")) {

Tree test = root.getTree("/").addChild(node);
test.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);

Tree a = test.addChild("jcr:content");
a.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);

Tree b = a.addChild("n");

b.setProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
b.setProperty("foo", "bar"+i);
i++;
}

root.commit();

// Check ordering works for func and non func properties
assertOrderedPlanAndQuery(
"select * from [nt:base] order by upper([jcr:content/n/foo])",
"lucene:upper(/oak:index/upper)", asList("/a","/c","/b","/e","/d"));

assertOrderedPlanAndQuery(
"select * from [nt:base] order by upper([jcr:content/n/foo]) DESC",
"lucene:upper(/oak:index/upper)", asList("/d","/e","/b","/c","/a"));

}

/*
Given an index def with 2 orderable property definitions(non-relative) for same property - one with function and one without
Indexer should index any changes properly and ordering should work as expected.
@@ -458,10 +458,9 @@ private boolean indexFunctionRestrictions(String path, D fields, NodeState state
PropertyState functionValue = calculateValue(path, state, pd.functionCode);
if (functionValue != null) {
if (pd.ordered) {
addTypedOrderedFields(fields, functionValue, pd.function, pd);
fieldAdded |= addTypedOrderedFields(fields, functionValue, pd.function, pd);
}
addTypedFields(fields, functionValue, pd.function, pd);
fieldAdded = true;
fieldAdded |= addTypedFields(fields, functionValue, pd.function, pd);
}
}
return fieldAdded;

0 comments on commit a0d1d8c

Please sign in to comment.