/// <summary> /// Initializes {@code treeKeyFrom} and {@code treeKeyTo} from the <seealso cref="IndexQuery query"/>. /// Geometry range queries makes an otherwise straight-forward key construction complex in that a geometry range internally is performed /// by executing multiple sub-range queries to the index. Each of those sub-range queries still needs to construct the full composite key - /// in the case of a composite index. Therefore this method can be called either with null or non-null {@code crs} and {@code range} and /// constructing a key when coming across a <seealso cref="IndexQuery.GeometryRangePredicate"/> will use the provided crs/range instead /// of the predicate, where the specific range is one out of many sub-ranges calculated from the <seealso cref="IndexQuery.GeometryRangePredicate"/> /// by the caller. /// </summary> /// <param name="treeKeyFrom"> the "from" key to construct from the query. </param> /// <param name="treeKeyTo"> the "to" key to construct from the query. </param> /// <param name="query"> the query to construct keys from to later send to <seealso cref="GBPTree"/> when reading. </param> /// <param name="crs"> <seealso cref="CoordinateReferenceSystem"/> for the specific {@code range}, if range is specified too. </param> /// <param name="range"> sub-range of a larger <seealso cref="IndexQuery.GeometryRangePredicate"/> to use instead of <seealso cref="IndexQuery.GeometryRangePredicate"/> /// in the query. </param> /// <returns> {@code true} if filtering is needed for the results from the reader, otherwise {@code false}. </returns> private bool InitializeRangeForGeometrySubQuery(GenericKey treeKeyFrom, GenericKey treeKeyTo, IndexQuery[] query, CoordinateReferenceSystem crs, SpaceFillingCurve.LongRange range) { bool needsFiltering = false; for (int i = 0; i < query.Length; i++) { IndexQuery predicate = query[i]; switch (predicate.Type()) { case exists: treeKeyFrom.InitValueAsLowest(i, ValueGroup.UNKNOWN); treeKeyTo.InitValueAsHighest(i, ValueGroup.UNKNOWN); break; case exact: IndexQuery.ExactPredicate exactPredicate = (IndexQuery.ExactPredicate)predicate; treeKeyFrom.InitFromValue(i, exactPredicate.Value(), NEUTRAL); treeKeyTo.InitFromValue(i, exactPredicate.Value(), NEUTRAL); break; case range: if (IsGeometryRangeQuery(predicate)) { // Use the supplied SpaceFillingCurve range instead of the GeometryRangePredicate because at the time of calling this method // the original geometry range have been split up into multiple sub-ranges and this invocation is for one of those sub-ranges. // We can not take query inclusion / exclusion into consideration here because then we risk missing border values. Always use // Inclusion.LOW / HIGH respectively and filter out points later on. treeKeyFrom.StateSlot(i).writePointDerived(crs, range.Min, LOW); treeKeyTo.StateSlot(i).writePointDerived(crs, range.Max + 1, HIGH); } else { //JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET: //ORIGINAL LINE: org.neo4j.internal.kernel.api.IndexQuery.RangePredicate<?> rangePredicate = (org.neo4j.internal.kernel.api.IndexQuery.RangePredicate<?>) predicate; IndexQuery.RangePredicate <object> rangePredicate = (IndexQuery.RangePredicate <object>)predicate; InitFromForRange(i, rangePredicate, treeKeyFrom); InitToForRange(i, rangePredicate, treeKeyTo); } break; case stringPrefix: IndexQuery.StringPrefixPredicate prefixPredicate = (IndexQuery.StringPrefixPredicate)predicate; treeKeyFrom.StateSlot(i).initAsPrefixLow(prefixPredicate.Prefix()); treeKeyTo.StateSlot(i).initAsPrefixHigh(prefixPredicate.Prefix()); break; case stringSuffix: case stringContains: treeKeyFrom.InitValueAsLowest(i, ValueGroup.TEXT); treeKeyTo.InitValueAsHighest(i, ValueGroup.TEXT); needsFiltering = true; break; default: throw new System.ArgumentException("IndexQuery of type " + predicate.Type() + " is not supported."); } } return(needsFiltering); }
public override void Query(Org.Neo4j.Storageengine.Api.schema.IndexProgressor_NodeValueClient cursor, IndexOrder indexOrder, bool needsValues, params IndexQuery[] predicates) { // Spatial does not support providing values if (needsValues) { throw new System.InvalidOperationException("Spatial index does not support providing values"); } ValidateQuery(indexOrder, predicates); IndexQuery predicate = predicates[0]; SpatialIndexKey treeKeyFrom = layout.newKey(); SpatialIndexKey treeKeyTo = layout.newKey(); InitializeKeys(treeKeyFrom, treeKeyTo); switch (predicate.Type()) { case exists: StartSeekForExists(treeKeyFrom, treeKeyTo, cursor, predicate); break; case exact: StartSeekForExact(treeKeyFrom, treeKeyTo, cursor, ((IndexQuery.ExactPredicate)predicate).value(), predicate); break; case range: IndexQuery.GeometryRangePredicate rangePredicate = (IndexQuery.GeometryRangePredicate)predicate; if (!rangePredicate.Crs().Equals(_spatial.crs)) { throw new System.ArgumentException("IndexQuery on spatial index with mismatching CoordinateReferenceSystem: " + rangePredicate.Crs() + " != " + _spatial.crs); } StartSeekForRange(cursor, rangePredicate, predicates); break; default: throw new System.ArgumentException("IndexQuery of type " + predicate.Type() + " is not supported."); } }
public override void Initialize(IndexDescriptor descriptor, IndexProgressor progressor, IndexQuery[] query, IndexOrder indexOrder, bool needsValues) { Debug.Assert(query != null); base.Initialize(progressor); _sortedMergeJoin.initialize(indexOrder); this._indexOrder = indexOrder; this._needsValues = needsValues; this._query = query; if (_read.hasTxStateWithChanges() && query.Length > 0) { IndexQuery firstPredicate = query[0]; switch (firstPredicate.Type()) { case exact: // No need to order, all values are the same this._indexOrder = IndexOrder.NONE; SeekQuery(descriptor, query); break; case exists: SetNeedsValuesIfRequiresOrder(); ScanQuery(descriptor); break; case range: Debug.Assert(query.Length == 1); SetNeedsValuesIfRequiresOrder(); RangeQuery(descriptor, (IndexQuery.RangePredicate)firstPredicate); break; case stringPrefix: Debug.Assert(query.Length == 1); SetNeedsValuesIfRequiresOrder(); PrefixQuery(descriptor, (IndexQuery.StringPrefixPredicate)firstPredicate); break; case stringSuffix: case stringContains: Debug.Assert(query.Length == 1); SuffixOrContainsQuery(descriptor, firstPredicate); break; default: throw new System.NotSupportedException("Query not supported: " + Arrays.ToString(query)); } } }
private Org.Neo4j.Storageengine.Api.schema.IndexProgressor_NodeValueClient InjectFullValuePrecision(Org.Neo4j.Storageengine.Api.schema.IndexProgressor_NodeValueClient cursor, IndexQuery[] query, IndexReader reader) { Org.Neo4j.Storageengine.Api.schema.IndexProgressor_NodeValueClient target = cursor; if (!reader.HasFullValuePrecision(query)) { IndexQuery[] filters = new IndexQuery[query.Length]; int count = 0; for (int i = 0; i < query.Length; i++) { IndexQuery q = query[i]; switch (q.Type()) { case range: ValueGroup valueGroup = q.ValueGroup(); if ((valueGroup == NUMBER || valueGroup == GEOMETRY) && !reader.HasFullValuePrecision(q)) { filters[i] = q; count++; } break; case exact: Value value = ((IndexQuery.ExactPredicate)q).value(); if (value.ValueGroup() == ValueGroup.NUMBER || Values.isArrayValue(value) || value.ValueGroup() == ValueGroup.GEOMETRY) { if (!reader.HasFullValuePrecision(q)) { filters[i] = q; count++; } } break; default: break; } } if (count > 0) { // filters[] can contain null elements. The non-null elements are the filters and each sit in the designated slot // matching the values from the index. target = new NodeValueClientFilter(target, _cursors.allocateNodeCursor(), _cursors.allocatePropertyCursor(), this, filters); } } return(target); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: private org.apache.lucene.search.Query toLuceneQuery(org.neo4j.internal.kernel.api.IndexQuery... predicates) throws org.neo4j.internal.kernel.api.exceptions.schema.IndexNotApplicableKernelException private Query ToLuceneQuery(params IndexQuery[] predicates) { IndexQuery predicate = predicates[0]; switch (predicate.Type()) { case exact: Value[] values = new Value[predicates.Length]; for (int i = 0; i < predicates.Length; i++) { Debug.Assert(predicates[i].Type() == exact, "Exact followed by another query predicate type is not supported at this moment."); values[i] = ((IndexQuery.ExactPredicate)predicates[i]).value(); } return(LuceneDocumentStructure.newSeekQuery(values)); case exists: foreach (IndexQuery p in predicates) { if (p.Type() != IndexQuery.IndexQueryType.exists) { throw new IndexNotApplicableKernelException("Exists followed by another query predicate type is not supported."); } } return(LuceneDocumentStructure.newScanQuery()); case range: AssertNotComposite(predicates); switch (predicate.ValueGroup()) { case NUMBER: IndexQuery.NumberRangePredicate np = (IndexQuery.NumberRangePredicate)predicate; return(LuceneDocumentStructure.newInclusiveNumericRangeSeekQuery(np.From(), np.To())); case TEXT: IndexQuery.TextRangePredicate sp = (IndexQuery.TextRangePredicate)predicate; return(LuceneDocumentStructure.newRangeSeekByStringQuery(sp.From(), sp.FromInclusive(), sp.To(), sp.ToInclusive())); default: throw new System.NotSupportedException(format("Range scans of value group %s are not supported", predicate.ValueGroup())); } case stringPrefix: AssertNotComposite(predicates); IndexQuery.StringPrefixPredicate spp = (IndexQuery.StringPrefixPredicate)predicate; return(LuceneDocumentStructure.newRangeSeekByPrefixQuery(spp.Prefix().stringValue())); case stringContains: AssertNotComposite(predicates); IndexQuery.StringContainsPredicate scp = (IndexQuery.StringContainsPredicate)predicate; return(LuceneDocumentStructure.newWildCardStringQuery(scp.Contains().stringValue())); case stringSuffix: AssertNotComposite(predicates); IndexQuery.StringSuffixPredicate ssp = (IndexQuery.StringSuffixPredicate)predicate; return(LuceneDocumentStructure.newSuffixStringQuery(ssp.Suffix().stringValue())); default: // todo figure out a more specific exception throw new Exception("Index query not supported: " + Arrays.ToString(predicates)); } }