| using Lucene.Net.Queries.Function; |
| using Lucene.Net.Queries.Function.ValueSources; |
| using Lucene.Net.Search; |
| using System; |
| using System.Collections.Generic; |
| |
| namespace Lucene.Net.Expressions |
| { |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /// <summary> |
| /// Simple class that binds expression variable names to |
| /// <see cref="Lucene.Net.Search.SortField"/>s or other |
| /// <see cref="Expression"/>s. |
| /// <para/> |
| /// Example usage: |
| /// <code> |
| /// SimpleBindings bindings = new SimpleBindings(); |
| /// // document's text relevance score |
| /// bindings.Add(new SortField("_score", SortFieldType.SCORE)); |
| /// // integer NumericDocValues field (or from FieldCache) |
| /// bindings.Add(new SortField("popularity", SortFieldType.INT)); |
| /// // another expression |
| /// bindings.Add("recency", myRecencyExpression); |
| /// // create a sort field in reverse order |
| /// Sort sort = new Sort(expr.GetSortField(bindings, true)); |
| /// </code> |
| /// @lucene.experimental |
| /// </summary> |
| public sealed class SimpleBindings : Bindings |
| { |
| internal readonly IDictionary<string, object> map = new Dictionary<string, object>(); |
| |
| /// <summary> |
| /// Creates a new empty <see cref="Bindings"/> |
| /// </summary> |
| public SimpleBindings() { } |
| |
| /// <summary>Adds a <see cref="SortField"/> to the bindings.</summary> |
| /// <remarks> |
| /// Adds a <see cref="SortField"/> to the bindings. |
| /// <para/> |
| /// This can be used to reference a DocValuesField, a field from |
| /// FieldCache, the document's score, etc. |
| /// </remarks> |
| public void Add(SortField sortField) |
| { |
| map[sortField.Field] = sortField; |
| } |
| |
| /// <summary>Adds an <see cref="Expression"/> to the bindings.</summary> |
| /// <remarks> |
| /// Adds an <see cref="Expression"/> to the bindings. |
| /// <para/> |
| /// This can be used to reference expressions from other expressions. |
| /// </remarks> |
| public void Add(string name, Expression expression) |
| { |
| map[name] = expression; |
| } |
| |
| public override ValueSource GetValueSource(string name) |
| { |
| object o; |
| // LUCENENET NOTE: Directly looking up a missing key will throw a KeyNotFoundException |
| if (!map.TryGetValue(name, out o)) |
| { |
| throw new ArgumentException("Invalid reference '" + name + "'"); |
| } |
| var expression = o as Expression; |
| if (expression != null) |
| { |
| return expression.GetValueSource(this); |
| } |
| SortField field = (SortField)o; |
| switch (field.Type) |
| { |
| case SortFieldType.INT32: |
| { |
| return new Int32FieldSource(field.Field, (FieldCache.IInt32Parser)field.Parser); |
| } |
| |
| case SortFieldType.INT64: |
| { |
| return new Int64FieldSource(field.Field, (FieldCache.IInt64Parser)field.Parser); |
| } |
| |
| case SortFieldType.SINGLE: |
| { |
| return new SingleFieldSource(field.Field, (FieldCache.ISingleParser)field.Parser); |
| } |
| |
| case SortFieldType.DOUBLE: |
| { |
| return new DoubleFieldSource(field.Field, (FieldCache.IDoubleParser)field.Parser); |
| } |
| |
| case SortFieldType.SCORE: |
| { |
| return GetScoreValueSource(); |
| } |
| |
| default: |
| { |
| throw new NotSupportedException(); |
| } |
| } |
| } |
| |
| /// <summary>Traverses the graph of bindings, checking there are no cycles or missing references</summary> |
| /// <exception cref="ArgumentException">if the bindings is inconsistent</exception> |
| public void Validate() |
| { |
| foreach (object o in map.Values) |
| { |
| if (o is Expression) |
| { |
| Expression expr = (Expression)o; |
| |
| expr.GetValueSource(this); |
| } |
| } |
| } |
| } |
| } |