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 am...@apache.org on 2014/10/29 07:17:48 UTC

svn commit: r1635060 - in /jackrabbit/oak/trunk/oak-lucene/src: main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java

Author: amitj
Date: Wed Oct 29 06:17:47 2014
New Revision: 1635060

URL: http://svn.apache.org/r1635060
Log:
OAK-2196: Implement sorting based on Lucene sorting
For ordered fields try conversion to defined type from the actual type if different and log warning and ignore if conversion fails.

Modified:
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
    jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java?rev=1635060&r1=1635059&r2=1635060&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java Wed Oct 29 06:17:47 2014
@@ -211,6 +211,9 @@ public class LuceneIndexEditor implement
         } catch (IOException e) {
             throw new CommitFailedException("Lucene", 3,
                     "Failed to index the node " + path, e);
+        } catch (IllegalArgumentException ie) {
+            throw new CommitFailedException("Lucene", 3,
+                "Failed to index the node " + path, ie);
         }
         return false;
     }
@@ -323,36 +326,65 @@ public class LuceneIndexEditor implement
 
     private boolean addTypedOrderedFields(List<Field> fields, PropertyState property) throws CommitFailedException {
         int tag = property.getType().tag();
+
+        int idxDefinedTag = getIndexDefinitionType(property);
+        // Try converting type to the defined type in the index definition
+        if (tag != idxDefinedTag) {
+            log.debug(
+                "Ordered property defined with type {} differs from property {} with type {} in " +
+                    "path {}",
+                Type.fromTag(idxDefinedTag, false), property.toString(), Type.fromTag(tag, false),
+                getPath());
+            tag = idxDefinedTag;
+        }
+
         String name = FieldNames.createDocValFieldName(property.getName());
         boolean fieldAdded = false;
         for (int i = 0; i < property.count(); i++) {
             Field f = null;
-            if (tag == Type.LONG.tag()) {
-                //TODO Distinguish fields which need to be used for search and for sort
-                //If a field is only used for Sort then it can be stored with less precision
-                f = new NumericDocValuesField(name, property.getValue(Type.LONG, i));
-            } else if (tag == Type.DATE.tag()) {
-                String date = property.getValue(Type.DATE, i);
-                f = new NumericDocValuesField(name, FieldFactory.dateToLong(date));
-            } else if (tag == Type.DOUBLE.tag()) {
-                f = new DoubleDocValuesField(name, property.getValue(Type.DOUBLE, i));
-            } else if (tag == Type.BOOLEAN.tag()) {
-                f = new SortedDocValuesField(name,
+            try {
+                if (tag == Type.LONG.tag()) {
+                    //TODO Distinguish fields which need to be used for search and for sort
+                    //If a field is only used for Sort then it can be stored with less precision
+                    f = new NumericDocValuesField(name, property.getValue(Type.LONG, i));
+                } else if (tag == Type.DATE.tag()) {
+                    String date = property.getValue(Type.DATE, i);
+                    f = new NumericDocValuesField(name, FieldFactory.dateToLong(date));
+                } else if (tag == Type.DOUBLE.tag()) {
+                    f = new DoubleDocValuesField(name, property.getValue(Type.DOUBLE, i));
+                } else if (tag == Type.BOOLEAN.tag()) {
+                    f = new SortedDocValuesField(name,
                         new BytesRef(property.getValue(Type.BOOLEAN, i).toString()));
-            } else if (tag == Type.STRING.tag()) {
-                f = new SortedDocValuesField(name,
+                } else if (tag == Type.STRING.tag()) {
+                    f = new SortedDocValuesField(name,
                         new BytesRef(property.getValue(Type.STRING, i)));
-            }
+                }
 
-            if (f != null) {
-                this.context.indexUpdate();
-                fields.add(f);
-                fieldAdded = true;
+                if (f != null) {
+                    this.context.indexUpdate();
+                    fields.add(f);
+                    fieldAdded = true;
+                }
+            } catch (Exception e) {
+                log.warn(
+                    "Ignoring ordered property. Could not convert property {} of type {} to type " +
+                        "{} for path {}",
+                    property, Type.fromTag(property.getType().tag(), false),
+                    Type.fromTag(tag, false), getPath(), e);
             }
         }
         return fieldAdded;
     }
 
+    private int getIndexDefinitionType(PropertyState property) {
+        int idxDefinedTag =
+            context.getDefinition().getPropDefn(property.getName()).getPropertyType();
+        if (idxDefinedTag == Type.UNDEFINED.tag()) {
+            idxDefinedTag = Type.STRING.tag();
+        }
+        return idxDefinedTag;
+    }
+
     private static boolean isVisible(String name) {
         return name.charAt(0) != ':';
     }

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=1635060&r1=1635059&r2=1635060&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 Wed Oct 29 06:17:47 2014
@@ -30,6 +30,7 @@ import javax.jcr.PropertyType;
 
 import com.google.common.collect.ComparisonChain;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.Oak;
@@ -482,7 +483,9 @@ public class LucenePropertyIndexTest ext
         root.commit();
 
         assertOrderedQuery("select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo]", getSortedPaths(tuples, OrderDirection.ASC));
-        assertOrderedQuery("select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo] DESC", getSortedPaths(tuples, OrderDirection.DESC));
+        assertOrderedQuery(
+            "select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo] DESC",
+            getSortedPaths(tuples, OrderDirection.DESC));
     }
 
     @Test
@@ -518,7 +521,9 @@ public class LucenePropertyIndexTest ext
         root.commit();
 
         assertOrderedQuery("select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo]", getSortedPaths(tuples, OrderDirection.ASC));
-        assertOrderedQuery("select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo] DESC", getSortedPaths(tuples, OrderDirection.DESC));
+        assertOrderedQuery(
+            "select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo] DESC",
+            getSortedPaths(tuples, OrderDirection.DESC));
     }
 
     @Test
@@ -555,8 +560,46 @@ public class LucenePropertyIndexTest ext
         }
         root.commit();
 
-        assertOrderedQuery("select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo]", getSortedPaths(tuples, OrderDirection.ASC));
-        assertOrderedQuery("select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo] DESC", getSortedPaths(tuples, OrderDirection.DESC));
+        assertOrderedQuery("select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo]",
+            getSortedPaths(tuples, OrderDirection.ASC));
+        assertOrderedQuery(
+            "select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo] DESC",
+            getSortedPaths(tuples, OrderDirection.DESC));
+    }
+
+    @Test
+    public void sortQueriesWithDateStringMixed_OrderedProps() throws Exception {
+        Tree idx = createIndex("test1", of("foo", "bar"));
+        idx.setProperty(createProperty(INCLUDE_PROPERTY_NAMES, of("bar"), STRINGS));
+        idx.setProperty(createProperty(ORDERED_PROP_NAMES, of("foo"), STRINGS));
+        Tree propIdx = idx.addChild(PROP_NODE).addChild("foo");
+        propIdx.setProperty(LuceneIndexConstants.PROP_TYPE, PropertyType.TYPENAME_DATE);
+        root.commit();
+
+        Tree test = root.getTree("/").addChild("test");
+        List<Calendar> values = createDates(NUMBER_OF_NODES);
+        List<Tuple> tuples = Lists.newArrayListWithCapacity(values.size());
+        for(int i = 0; i < values.size(); i++){
+            Tree child = test.addChild("n"+i);
+            child.setProperty("bar", "baz");
+            if (i != 0) {
+                child.setProperty("foo", values.get(i));
+                tuples.add(new Tuple(values.get(i), child.getPath()));
+            } else {
+                child.setProperty("foo", String.valueOf(values.get(i).getTimeInMillis()));
+            }
+        }
+        root.commit();
+
+        // Add the path of property added as timestamp string in the sorted list
+        assertOrderedQuery("select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo]",
+            Lists.newArrayList(Iterables.concat(Lists.newArrayList("/test/n0"),
+                getSortedPaths(tuples, OrderDirection.ASC))));
+        // Append the path of property added as timestamp string to the sorted list
+        assertOrderedQuery(
+            "select [jcr:path] from [nt:base] where [bar] = 'baz' order by [foo] DESC", Lists
+            .newArrayList(Iterables.concat(getSortedPaths(tuples, OrderDirection.DESC),
+                Lists.newArrayList("/test/n0"))));
     }
 
     @Test