Skip to content

Commit

Permalink
adds support for range query on Lucene module
Browse files Browse the repository at this point in the history
refs #6534
  • Loading branch information
robfrank committed Dec 15, 2016
1 parent 4899db1 commit d9a96ea
Show file tree
Hide file tree
Showing 10 changed files with 353 additions and 175 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,14 @@ public static Field createField(String fieldName, Object value, Field.Store stor

if (value instanceof Number) {
Number number = (Number) value;
if (value instanceof Long)
if (value instanceof Long) {
return new LongField(fieldName, number.longValue(), store);
else if (value instanceof Float)
} else if (value instanceof Float) {
return new FloatField(fieldName, number.floatValue(), store);
else if (value instanceof Double)
} else if (value instanceof Double) {
return new DoubleField(fieldName, number.doubleValue(), store);

}
return new IntField(fieldName, number.intValue(), store);

} else if (value instanceof Date) {
return new LongField(fieldName, ((Date) value).getTime(), store);
}
Expand Down Expand Up @@ -104,10 +103,6 @@ public static Query createExactQuery(OIndexDefinition index, Object key) {
return query;
}

public static Query createQueryId(OIdentifiable value) {
return new TermQuery(new Term(OLuceneIndexEngineAbstract.RID, value.getIdentity().toString()));
}

public static Query createDeleteQuery(OIdentifiable value, List<String> fields, Object key) {

final BooleanQuery.Builder queryBuilder = new BooleanQuery.Builder();
Expand All @@ -127,6 +122,10 @@ public static Query createDeleteQuery(OIdentifiable value, List<String> fields,
return queryBuilder.build();
}

public static Query createQueryId(OIdentifiable value) {
return new TermQuery(new Term(OLuceneIndexEngineAbstract.RID, value.getIdentity().toString()));
}

public static Query createFullQuery(OIndexDefinition index, Object key, Analyzer analyzer) throws ParseException {

String query = "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@
package com.orientechnologies.lucene.builder;

import com.orientechnologies.common.log.OLogManager;
import com.orientechnologies.lucene.parser.OLuceneMultiFieldQueryParser;
import com.orientechnologies.orient.core.index.OCompositeKey;
import com.orientechnologies.orient.core.index.OIndexDefinition;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.parser.ParseException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.Query;

import java.util.HashMap;
import java.util.Map;

/**
Expand Down Expand Up @@ -82,26 +83,30 @@ public Query query(OIndexDefinition index, Object key, Analyzer analyzer) throws
}

protected Query getQueryParser(OIndexDefinition index, String key, Analyzer analyzer) throws ParseException {
QueryParser queryParser;
if ((key).startsWith("(")) {
queryParser = new QueryParser("", analyzer);

String[] fields;
if (index.isAutomatic()) {
fields = index.getFields().toArray(new String[index.getFields().size()]);
} else {
String[] fields;
if (index.isAutomatic()) {
fields = index.getFields().toArray(new String[index.getFields().size()]);
} else {
int length = index.getTypes().length;
int length = index.getTypes().length;

fields = new String[length];
for (int i = 0; i < length; i++) {
fields[i] = "k" + i;
}
fields = new String[length];
for (int i = 0; i < length; i++) {
fields[i] = "k" + i;
}
}

Map<String, OType> types = new HashMap<String, OType>();
for (int i = 0; i < fields.length; i++) {
String field = fields[i];
types.put(field, index.getTypes()[i]);

queryParser = new MultiFieldQueryParser(fields, analyzer);
}

// for (Map.Entry<String, OType> typeEntry : types.entrySet()) {
// System.out.println("typeEntry = " + typeEntry);
// }
final OLuceneMultiFieldQueryParser queryParser = new OLuceneMultiFieldQueryParser(types, fields, analyzer);
queryParser.setAllowLeadingWildcard(allowLeadingWildcard);

queryParser.setLowercaseExpandedTerms(lowercaseExpandedTerms);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,53 +31,11 @@

public class OLuceneOperatorUtil {

public static boolean checkIndexExistence(final OClass iSchemaClass, final OIndexSearchResult result) {
if (!iSchemaClass.areIndexed(result.fields()))
return false;

if (result.lastField.isLong()) {
final int fieldCount = result.lastField.getItemCount();
OClass cls = iSchemaClass.getProperty(result.lastField.getItemName(0)).getLinkedClass();

for (int i = 1; i < fieldCount; i++) {
if (cls == null || !cls.areIndexed(result.lastField.getItemName(i))) {
return false;
}
public static OIndexSearchResult buildOIndexSearchResult(OClass iSchemaClass,
OSQLFilterCondition iCondition,
List<OIndexSearchResult> iIndexSearchResults,
OCommandContext context) {

cls = cls.getProperty(result.lastField.getItemName(i)).getLinkedClass();
}
}
return true;
}

public static OIndexSearchResult createIndexedProperty(final OSQLFilterCondition iCondition, final Object iItem) {
if (iItem == null || !(iItem instanceof OSQLFilterItemField))
return null;

if (iCondition.getLeft() instanceof OSQLFilterItemField && iCondition.getRight() instanceof OSQLFilterItemField)
return null;

final OSQLFilterItemField item = (OSQLFilterItemField) iItem;

if (item.hasChainOperators() && !item.isFieldChain())
return null;

final Object origValue = iCondition.getLeft() == iItem ? iCondition.getRight() : iCondition.getLeft();

if (iCondition.getOperator() instanceof OQueryOperatorBetween || iCondition.getOperator() instanceof OQueryOperatorIn) {
return new OIndexSearchResult(iCondition.getOperator(), item.getFieldChain(), origValue);
}

final Object value = OSQLHelper.getValue(origValue);

if (value == null)
return null;

return new OIndexSearchResult(iCondition.getOperator(), item.getFieldChain(), value);
}

public static OIndexSearchResult buildOIndexSearchResult(OClass iSchemaClass, OSQLFilterCondition iCondition,
List<OIndexSearchResult> iIndexSearchResults, OCommandContext context) {
if (iCondition.getLeft() instanceof Collection) {
OIndexSearchResult lastResult = null;

Expand Down Expand Up @@ -132,4 +90,49 @@ public static OIndexSearchResult buildOIndexSearchResult(OClass iSchemaClass, OS
}
}

public static boolean checkIndexExistence(final OClass iSchemaClass, final OIndexSearchResult result) {
if (!iSchemaClass.areIndexed(result.fields()))
return false;

if (result.lastField.isLong()) {
final int fieldCount = result.lastField.getItemCount();
OClass cls = iSchemaClass.getProperty(result.lastField.getItemName(0)).getLinkedClass();

for (int i = 1; i < fieldCount; i++) {
if (cls == null || !cls.areIndexed(result.lastField.getItemName(i))) {
return false;
}

cls = cls.getProperty(result.lastField.getItemName(i)).getLinkedClass();
}
}
return true;
}

public static OIndexSearchResult createIndexedProperty(final OSQLFilterCondition iCondition, final Object iItem) {
if (iItem == null || !(iItem instanceof OSQLFilterItemField))
return null;

if (iCondition.getLeft() instanceof OSQLFilterItemField && iCondition.getRight() instanceof OSQLFilterItemField)
return null;

final OSQLFilterItemField item = (OSQLFilterItemField) iItem;

if (item.hasChainOperators() && !item.isFieldChain())
return null;

final Object origValue = iCondition.getLeft() == iItem ? iCondition.getRight() : iCondition.getLeft();

if (iCondition.getOperator() instanceof OQueryOperatorBetween || iCondition.getOperator() instanceof OQueryOperatorIn) {
return new OIndexSearchResult(iCondition.getOperator(), item.getFieldChain(), origValue);
}

final Object value = OSQLHelper.getValue(origValue);

if (value == null)
return null;

return new OIndexSearchResult(iCondition.getOperator(), item.getFieldChain(), value);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,21 @@
import com.orientechnologies.orient.core.sql.operator.OIndexReuseType;
import com.orientechnologies.orient.core.sql.operator.OQueryTargetOperator;
import com.orientechnologies.orient.core.sql.parser.ParseException;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.memory.MemoryIndex;
import org.apache.lucene.search.Query;

import java.util.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

public class OLuceneTextOperator extends OQueryTargetOperator {

public static final String MEMORY_INDEX = "_memoryIndex";

public OLuceneTextOperator() {
this("LUCENE", 5, false);
}
Expand All @@ -55,24 +61,30 @@ public OLuceneTextOperator(String iKeyword, int iPrecedence, boolean iLogical) {
super(iKeyword, iPrecedence, iLogical);
}

protected static ODatabaseDocumentInternal getDatabase() {
return ODatabaseRecordThreadLocal.INSTANCE.get();
@Override
public OIndexReuseType getIndexReuseType(Object iLeft, Object iRight) {
return OIndexReuseType.INDEX_OPERATOR;
}

@Override
public OIndexSearchResult getOIndexSearchResult(OClass iSchemaClass, OSQLFilterCondition iCondition,
List<OIndexSearchResult> iIndexSearchResults, OCommandContext context) {
// FIXME questo non trova l'indice se l'ordine e' errato
OIndexSearchResult result = OLuceneOperatorUtil.buildOIndexSearchResult(iSchemaClass, iCondition,
iIndexSearchResults, context);

return result;
}

@Override
public OIndexCursor executeIndexQuery(OCommandContext iContext, OIndex<?> index, List<Object> keyParams, boolean ascSortOrder) {
OIndexCursor cursor;

Object indexResult = index.get(new OFullTextCompositeKey(keyParams).setContext(iContext));

if (indexResult == null || indexResult instanceof OIdentifiable)
cursor = new OIndexCursorSingleValue((OIdentifiable) indexResult, new OFullTextCompositeKey(keyParams));
else
cursor = new OIndexCursorCollectionValue(((Collection<OIdentifiable>) indexResult), new OFullTextCompositeKey(keyParams));
return cursor;
}
return new OIndexCursorSingleValue((OIdentifiable) indexResult, new OFullTextCompositeKey(keyParams));

@Override
public OIndexReuseType getIndexReuseType(Object iLeft, Object iRight) {
return OIndexReuseType.INDEX_OPERATOR;
return new OIndexCursorCollectionValue(((Collection<OIdentifiable>) indexResult), new OFullTextCompositeKey(keyParams));
}

@Override
Expand All @@ -86,11 +98,8 @@ public ORID getEndRidRange(Object iLeft, Object iRight) {
}

@Override
public OIndexSearchResult getOIndexSearchResult(OClass iSchemaClass, OSQLFilterCondition iCondition,
List<OIndexSearchResult> iIndexSearchResults, OCommandContext context) {

// FIXME questo non trova l'indice se l'ordine e' errato
return OLuceneOperatorUtil.buildOIndexSearchResult(iSchemaClass, iCondition, iIndexSearchResults, context);
public boolean canBeMerged() {
return false;
}

@Override
Expand All @@ -104,35 +113,31 @@ public Object evaluateRecord(OIdentifiable iRecord, ODocument iCurrentResult, OS
Object iRight, OCommandContext iContext) {

OLuceneFullTextIndex index = involvedIndex(iRecord, iCurrentResult, iCondition, iLeft, iRight);

if (index == null) {
throw new OCommandExecutionException("Cannot evaluate lucene condition without index configuration.");
}

MemoryIndex memoryIndex = (MemoryIndex) iContext.getVariable("_memoryIndex");
MemoryIndex memoryIndex = (MemoryIndex) iContext.getVariable(MEMORY_INDEX);
if (memoryIndex == null) {
memoryIndex = new MemoryIndex();
iContext.setVariable("_memoryIndex", memoryIndex);
iContext.setVariable(MEMORY_INDEX, memoryIndex);
}
memoryIndex.reset();

Document doc = null;
try {
doc = index.buildDocument(iLeft);
} catch (Exception e) {
e.printStackTrace();
}
for (IndexableField field : index.buildDocument(iLeft).getFields()) {
memoryIndex.addField(field.name(), field.tokenStream(index.indexAnalyzer(), null));
}
return memoryIndex.search(index.buildQuery(iRight)) > 0.0f;

for (IndexableField field : doc.getFields()) {
memoryIndex.addField(field.name(), field.stringValue(), index.indexAnalyzer());
}
Query query = null;
try {
query = index.buildQuery(iRight);
} catch (ParseException e) {
OLogManager.instance().error(this, "error occurred while building query", e);

} catch (IOException e) {
OLogManager.instance().error(this, "error occurred while building memory index", e);

}
return memoryIndex.search(query) > 0.0f;
return null;
}

protected OLuceneFullTextIndex involvedIndex(OIdentifiable iRecord, ODocument iCurrentResult, OSQLFilterCondition iCondition,
Expand Down Expand Up @@ -166,6 +171,10 @@ protected OLuceneFullTextIndex involvedIndex(OIdentifiable iRecord, ODocument iC
return idx;
}

protected static ODatabaseDocumentInternal getDatabase() {
return ODatabaseRecordThreadLocal.INSTANCE.get();
}

private boolean isChained(Object left) {
if (left instanceof OSQLFilterItemField) {
OSQLFilterItemField field = (OSQLFilterItemField) left;
Expand Down Expand Up @@ -204,9 +213,4 @@ protected Collection<String> fields(OSQLFilterCondition iCondition) {
}
return Collections.emptyList();
}

@Override
public boolean canBeMerged() {
return false;
}
}
Loading

0 comments on commit d9a96ea

Please sign in to comment.