/// <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);
        }
示例#2
0
        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.");
            }
        }
示例#3
0
        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));
                }
            }
        }
示例#4
0
文件: Read.cs 项目: Neo4Net/Neo4Net
        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);
        }
示例#5
0
//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));
            }
        }