Пример #1
0
        private static Term CreateTerm(string name, QueryFieldValue queryFieldValue)
        {
            string numval;

            switch (queryFieldValue.Datatype)
            {
            case IndexableDataType.String:
                return(new Term(name, queryFieldValue.StringValue));

            case IndexableDataType.Int: numval = NumericUtils.IntToPrefixCoded(queryFieldValue.IntValue); break;

            case IndexableDataType.Long: numval = NumericUtils.LongToPrefixCoded(queryFieldValue.LongValue); break;

            case IndexableDataType.Float: numval = NumericUtils.FloatToPrefixCoded(queryFieldValue.SingleValue); break;

            case IndexableDataType.Double: numval = NumericUtils.DoubleToPrefixCoded(queryFieldValue.DoubleValue); break;

            default:
                throw new SnNotSupportedException("Unknown IndexableDataType enum value: " + queryFieldValue.Datatype);
            }

            var numterm = new Term(name, numval);

            return(numterm);
        }
Пример #2
0
        public void AddPoint(int id, string name, double lat, double lng, IndexWriter currentWriter)
        {
            EnsureDistanceMatrixReady();
            var      writer = currentWriter != null ? currentWriter : MakeWriter(true, IndexWriter.MaxFieldLength.UNLIMITED);
            Document doc    = new Document();

            doc.Add(new Field("name", name, Field.Store.YES, Field.Index.ANALYZED));
            doc.Add(new Field("PostID", Convert.ToString(id), Field.Store.YES, Field.Index.UN_TOKENIZED));

            // convert the lat / long to lucene fields
            doc.Add(new Field(LatField, NumericUtils.DoubleToPrefixCoded(lat), Field.Store.YES, Field.Index.NOT_ANALYZED));
            doc.Add(new Field(LngField, NumericUtils.DoubleToPrefixCoded(lng), Field.Store.YES, Field.Index.NOT_ANALYZED));

            // add a default meta field to make searching all documents easy
            doc.Add(new Field("metafile", "doc", Field.Store.YES, Field.Index.ANALYZED));

            int ctpsize = _ctps.Count;

            for (int i = 0; i < ctpsize; i++)
            {
                CartesianTierPlotter ctp = _ctps[i];
                var boxId = ctp.GetTierBoxId(lat, lng);
                doc.Add(new Field(ctp.GetTierFieldName(),
                                  NumericUtils.DoubleToPrefixCoded(boxId),
                                  Field.Store.YES,
                                  Field.Index.NOT_ANALYZED_NO_NORMS));
            }
            writer.AddDocument(doc);

            if (currentWriter == null)             // if we're not using the passed along writer, which is supposed to be terminated by the caller, then end our new writer
            {
                FinishWriter(writer);
            }
        }
Пример #3
0
        private Query CreateValueQuery(QueryFieldValue value)
        {
            var    currentField = _currentField.Peek();
            string numval;

            switch (value.Datatype)
            {
            case IndexableDataType.String:
                return(CreateStringValueQuery(value, currentField));

            case IndexableDataType.Int: numval = NumericUtils.IntToPrefixCoded(value.IntValue); break;

            case IndexableDataType.Long: numval = NumericUtils.LongToPrefixCoded(value.LongValue); break;

            case IndexableDataType.Float: numval = NumericUtils.FloatToPrefixCoded(value.SingleValue); break;

            case IndexableDataType.Double: numval = NumericUtils.DoubleToPrefixCoded(value.DoubleValue); break;

            default:
                throw new NotImplementedException("Unknown IndexableDataType enum value: " + value.Datatype);
            }
            var numterm = new Term(currentField.Name, numval);

            return(new TermQuery(numterm));
        }
Пример #4
0
        private void AddPoint(IndexWriter writer, String name, double lat, double lng)
        {
            Document doc = new Document();

            doc.Add(new Field("name", name, Field.Store.YES, Field.Index.ANALYZED));

            // convert the lat / long to lucene fields
            doc.Add(new Field(LatField, NumericUtils.DoubleToPrefixCoded(lat), Field.Store.YES, Field.Index.NOT_ANALYZED));
            doc.Add(new Field(LngField, NumericUtils.DoubleToPrefixCoded(lng), Field.Store.YES, Field.Index.NOT_ANALYZED));

            // add a default meta field to make searching all documents easy
            doc.Add(new Field("metafile", "doc", Field.Store.YES, Field.Index.ANALYZED));

            int ctpsize = _ctps.Count;

            for (int i = 0; i < ctpsize; i++)
            {
                CartesianTierPlotter ctp = _ctps[i];
                var boxId = ctp.GetTierBoxId(lat, lng);
                doc.Add(new Field(ctp.GetTierFieldName(),
                                  NumericUtils.DoubleToPrefixCoded(boxId),
                                  Field.Store.YES,
                                  Field.Index.NOT_ANALYZED_NO_NORMS));
            }
            writer.AddDocument(doc);
        }
Пример #5
0
        public static string Tier(int id, double lat, double lng)
        {
            if (id < MinTier || id > MaxTier)
            {
                throw new ArgumentException(
                          string.Format("tier id should be between {0} and {1}", MinTier, MaxTier), "id");
            }

            var boxId = Ctps[id - MinTier].GetTierBoxId(lat, lng);

            return(NumericUtils.DoubleToPrefixCoded(boxId));
        }
Пример #6
0
        private static string NumericStringToSortableNumeric(string value)
        {
            var number = NumberUtil.StringToNumber(value);

            if (number is long)
            {
                return(NumericUtils.LongToPrefixCoded((long)number));
            }
            if (number is double)
            {
                return(NumericUtils.DoubleToPrefixCoded((double)number));
            }

            throw new ArgumentException("Unknown type for " + number.GetType() + " which started as " + value);
        }
        public static EncodedFacetRange CreateFrom(FacetRange range)
        {
            var result = new EncodedFacetRange
            {
                Label         = range.Label,
                FromInclusive = range.FromInclusive,
                ToInclusive   = range.ToInclusive
            };

            if (range.FromValue != null)
            {
                result.FromValue = NumericUtils.DoubleToPrefixCoded(range.FromValue.Value);
            }
            if (range.ToValue != null)
            {
                result.ToValue = NumericUtils.DoubleToPrefixCoded(range.ToValue.Value);
            }

            return(result);
        }
Пример #8
0
            /// <summary>
            /// Makes a TermQuery for the given MappedField and expression.
            /// </summary>
            /// <param name="field">
            /// The MappedField to create the query for.
            /// </param>
            /// <param name="term">
            /// The constant to match in the query.
            /// </param>
            /// <returns>
            /// An instance of TermQuery.
            /// </returns>
            private static TermQuery MakeTermQuery(MappedField field, Expression term)
            {
                Debug.Assert(null != field, "The mapped field must not be null.");
                Debug.Assert(null != term, "The term must not be null.");

                string queryTerm;

                switch (field.Type)
                {
                case MappedField.FieldType.Float:
                    queryTerm = NumericUtils.FloatToPrefixCoded(field.GetValueFromExpression <float>(term));
                    break;

                case MappedField.FieldType.Double:
                    queryTerm = NumericUtils.DoubleToPrefixCoded(field.GetValueFromExpression <double>(term));
                    break;

                case MappedField.FieldType.Short:
                    queryTerm = NumericUtils.IntToPrefixCoded(field.GetValueFromExpression <short>(term));
                    break;

                case MappedField.FieldType.Int:
                    queryTerm = NumericUtils.IntToPrefixCoded(field.GetValueFromExpression <int>(term));
                    break;

                case MappedField.FieldType.Long:
                    queryTerm = NumericUtils.LongToPrefixCoded(field.GetValueFromExpression <long>(term));
                    break;

                case MappedField.FieldType.String:
                    queryTerm = field.GetValueFromExpression <string>(term);
                    break;

                default:
                    throw new InvalidOperationException(String.Format(
                                                            "Cannot make a TermQuery for field '{0}' of type {1}.",
                                                            field.Name, field.Type));
                }

                return(new TermQuery(new Term(field.Name, queryTerm)));
            }
Пример #9
0
        internal static string ToPrefixCoded(this ValueType value)
        {
            if (value is int)
            {
                return(NumericUtils.IntToPrefixCoded((int)value));
            }
            if (value is long)
            {
                return(NumericUtils.LongToPrefixCoded((long)value));
            }
            if (value is double)
            {
                return(NumericUtils.DoubleToPrefixCoded((double)value));
            }
            if (value is float)
            {
                return(NumericUtils.FloatToPrefixCoded((float)value));
            }

            throw new NotSupportedException("ValueType " + value.GetType() + " not supported.");
        }
        public void Set(string name, object value, Document document, Field.Store store, Field.Index index, float?boost)
        {
            var service  = (Service)value;
            var location = service.Location;
            var lat      = new Field("Location_Latitude", NumericUtils.DoubleToPrefixCoded(location.Y), Field.Store.YES, Field.Index.NOT_ANALYZED);
            var lng      = new Field("Location_Longitude", NumericUtils.DoubleToPrefixCoded(location.X), Field.Store.YES, Field.Index.NOT_ANALYZED);

            document.Add(lat);
            document.Add(lng);

            document.Add(new Field("metafile", "doc", Field.Store.YES, Field.Index.ANALYZED));

            int ctpsize = Ctps.Count;

            for (int i = 0; i < ctpsize; i++)
            {
                CartesianTierPlotter ctp = Ctps[i];
                var boxId = ctp.GetTierBoxId(location.Y, location.X);
                document.Add(new Field(ctp.GetTierFieldName(), NumericUtils.DoubleToPrefixCoded(boxId), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
            }
        }
        /// <summary>
        /// Converts to searchable.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="tryConvertToNumber">if set to <c>true</c> [try convert to number].</param>
        /// <returns></returns>
        public static string ConvertToSearchable(object value, bool tryConvertToNumber = true)
        {
            if (value == null || String.IsNullOrEmpty(value.ToString()))
            {
                return(String.Empty);
            }

            if (tryConvertToNumber)
            {
                decimal decimalVal;
                int     intVal;

                // Try converting to a known type
                if (Decimal.TryParse(value.ToString(), out decimalVal))
                {
                    value = decimalVal;
                }
                else if (Int32.TryParse(value.ToString(), out intVal))
                {
                    value = intVal;
                }
            }

            if (value is string)
            {
                return(value.ToString());
            }

            if (value is decimal)
            {
                return(NumericUtils.DoubleToPrefixCoded(double.Parse(value.ToString())));
            }

            if (value.GetType() != typeof(int) || value.GetType() != typeof(long) || value.GetType() != typeof(double))
            {
                return(value.ToString());
            }

            return(NumericUtils.DoubleToPrefixCoded((double)value));
        }
Пример #12
0
        private static (string Value, RangeType Type) ConvertFieldValue(string value, ValueTokenType type)
        {
            switch (type)
            {
            case ValueTokenType.Long:
                var lng = QueryBuilder.ParseInt64WithSeparators(value);
                return(NumericUtils.DoubleToPrefixCoded(lng), RangeType.Double);

            case ValueTokenType.Double:
                var dbl = double.Parse(value, CultureInfo.InvariantCulture);
                return(NumericUtils.DoubleToPrefixCoded(dbl), RangeType.Double);

            case ValueTokenType.String:
                return(value, RangeType.None);

            case ValueTokenType.Null:
                return(null, RangeType.None);

            default:
                throw new ArgumentOutOfRangeException(nameof(type), type, null);
            }
        }
        private static string GetFilterValue(string value, bool isBooleanField)
        {
            if (string.IsNullOrEmpty(value))
            {
                return(string.Empty);
            }

            if (isBooleanField)
            {
                return(bool.Parse(value).ToStringInvariant());
            }

            var dateValue = ConvertToDateTimeTicks(value);

            if (dateValue != null)
            {
                return(NumericUtils.LongToPrefixCoded(dateValue.Value));
            }

            var dobuleValue = ConvertToDouble(value);

            return(dobuleValue != null?NumericUtils.DoubleToPrefixCoded(dobuleValue.Value) : value);
        }
Пример #14
0
        private static string ConvertFieldValue(string field, string value)
        {
            if (NumberUtil.IsNull(value))
            {
                return(null);
            }

            var rangeType = FieldUtil.GetRangeTypeFromFieldName(field);

            switch (rangeType)
            {
            case RangeType.Long:
                var longValue = NumberUtil.StringToLong(value);
                return(NumericUtils.LongToPrefixCoded(longValue.Value));

            case RangeType.Double:
                var doubleValue = NumberUtil.StringToDouble(value);
                return(NumericUtils.DoubleToPrefixCoded(doubleValue.Value));

            default:
                return(value);
            }
        }
Пример #15
0
        private static (string Value, RangeType Type) ConvertFieldValue(string value, ValueTokenType type, BlittableJsonReaderObject queryParameters)
        {
            switch (type)
            {
            case ValueTokenType.Long:
                var lng = QueryBuilder.ParseInt64WithSeparators(value);
                return(NumericUtils.DoubleToPrefixCoded(lng), RangeType.Double);

            case ValueTokenType.Double:
                var dbl = double.Parse(value, CultureInfo.InvariantCulture);
                return(NumericUtils.DoubleToPrefixCoded(dbl), RangeType.Double);

            case ValueTokenType.String:
                return(value, RangeType.None);

            case ValueTokenType.Null:
                return(null, RangeType.None);

            case ValueTokenType.Parameter:
                queryParameters.TryGet(value, out object o);
                var rangeType = RangeType.None;
                if (o is long l)
                {
                    o         = NumericUtils.DoubleToPrefixCoded(l);
                    rangeType = RangeType.Double;
                }
                else if (o is LazyNumberValue lnv)
                {
                    o         = NumericUtils.DoubleToPrefixCoded((double)lnv);
                    rangeType = RangeType.Double;
                }
                return(o?.ToString(), rangeType);

            default:
                throw new ArgumentOutOfRangeException(nameof(type), type, null);
            }
        }
Пример #16
0
        public override DocIdSet GetDocIdSet(IndexReader reader)
        {
            var bits = new OpenBitSet(reader.MaxDoc());

            TermDocs      termDocs = reader.TermDocs();
            List <double> area     = _shape.Area;
            int           sz       = area.Count;

            // iterate through each boxid
            for (int i = 0; i < sz; i++)
            {
                double boxId = area[i];
                termDocs.Seek(new Term(_fieldName, NumericUtils.DoubleToPrefixCoded(boxId)));

                // iterate through all documents
                // which have this boxId
                while (termDocs.Next())
                {
                    bits.FastSet(termDocs.Doc());
                }
            }

            return(bits);
        }
Пример #17
0
        private string ConvertToTermValue(IndexValue value)
        {
            switch (value.Type)
            {
            case IndexValueType.String:      return(value.StringValue);

            case IndexValueType.StringArray: throw new NotSupportedException();

            case IndexValueType.Bool:        return(value.BooleanValue ? IndexValue.Yes : IndexValue.No);

            case IndexValueType.Int:         return(NumericUtils.IntToPrefixCoded(value.IntegerValue));

            case IndexValueType.Long:        return(NumericUtils.LongToPrefixCoded(value.LongValue));

            case IndexValueType.Float:       return(NumericUtils.FloatToPrefixCoded(value.SingleValue));

            case IndexValueType.Double:      return(NumericUtils.DoubleToPrefixCoded(value.DoubleValue));

            case IndexValueType.DateTime:    return(NumericUtils.LongToPrefixCoded(value.DateTimeValue.Ticks));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #18
0
 public static string Lng(double value)
 {
     return(NumericUtils.DoubleToPrefixCoded(value));
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="lookQuery">The query to parse</param>
        /// <param name="parsingContext"></param>
        private static void ParseLocationQuery(ParsingContext parsingContext, LookQuery lookQuery)
        {
            if (lookQuery.LocationQuery == null)
            {
                return;
            }

            parsingContext.QueryAdd(new TermQuery(new Term(LookConstants.HasLocationField, "1")), BooleanClause.Occur.MUST);

            if (lookQuery.LocationQuery.Boundary != null) // limit results within an lat lng fixed view (eg, typical map bounds)
            {
                parsingContext.QueryAdd(
                    new TermRangeQuery(
                        LookConstants.LocationField + "_Latitude",
                        NumericUtils.DoubleToPrefixCoded(lookQuery.LocationQuery.Boundary.LatitudeMin),
                        NumericUtils.DoubleToPrefixCoded(lookQuery.LocationQuery.Boundary.LatitudeMax),
                        true,
                        true),
                    BooleanClause.Occur.MUST);

                parsingContext.QueryAdd(
                    new TermRangeQuery(
                        LookConstants.LocationField + "_Longitude",
                        NumericUtils.DoubleToPrefixCoded(lookQuery.LocationQuery.Boundary.LongitudeMin),
                        NumericUtils.DoubleToPrefixCoded(lookQuery.LocationQuery.Boundary.LongitudeMax),
                        true,
                        true),
                    BooleanClause.Occur.MUST);
            }

            if (lookQuery.LocationQuery.Location != null) // location set, so can calculate distance
            {
                double maxDistance = LookService._maxDistance;

                if (lookQuery.LocationQuery.MaxDistance != null)
                {
                    maxDistance = Math.Min(lookQuery.LocationQuery.MaxDistance.GetMiles(), maxDistance);
                }

                var distanceQueryBuilder = new DistanceQueryBuilder(
                    lookQuery.LocationQuery.Location.Latitude,
                    lookQuery.LocationQuery.Location.Longitude,
                    maxDistance,
                    LookConstants.LocationField + "_Latitude",
                    LookConstants.LocationField + "_Longitude",
                    LookConstants.LocationTierFieldPrefix,
                    true);

                parsingContext.Filter = distanceQueryBuilder.Filter;

                if (lookQuery.SortOn == SortOn.Distance)
                {
                    parsingContext.Sort = new Sort(
                        new SortField(
                            LookConstants.DistanceField,
                            new DistanceFieldComparatorSource(distanceQueryBuilder.DistanceFilter)));
                }

                parsingContext.GetDistance = new Func <int, double?>(x =>
                {
                    if (distanceQueryBuilder.DistanceFilter.Distances.ContainsKey(x))
                    {
                        return(distanceQueryBuilder.DistanceFilter.Distances[x]);
                    }

                    return(null);
                });
            }
        }
Пример #20
0
        /// <summary>
        ///  Do the indexing and set the field values onto the Lucene document
        /// </summary>
        /// <param name="indexingContext"></param>
        /// <param name="document"></param>
        internal static void Index(IndexingContext indexingContext, Document document)
        {
            if (indexingContext.Item != null)
            {
                var publishedItemType = indexingContext?.HostItem?.ItemType ?? indexingContext.Item.ItemType;

                var hasNodeField = new Field(
                    LookConstants.HasNodeField,
                    "1",
                    Field.Store.NO,
                    Field.Index.NOT_ANALYZED);

                var nodeIdField = new Field(
                    LookConstants.NodeIdField,
                    indexingContext.Item.Id.ToString(),
                    Field.Store.YES,
                    Field.Index.NOT_ANALYZED);

                var nodeKeyField = new Field(
                    LookConstants.NodeKeyField,
                    indexingContext.Item.GetGuidKey().ToString(),
                    Field.Store.YES,
                    Field.Index.NOT_ANALYZED);

                var nodeTypeField = new Field(
                    LookConstants.NodeTypeField,
                    publishedItemType.ToString(),
                    Field.Store.YES,
                    Field.Index.NOT_ANALYZED,
                    Field.TermVector.NO);

                var nodeAliasField = new Field(
                    LookConstants.NodeAliasField,
                    indexingContext.Item.DocumentTypeAlias,
                    Field.Store.NO,
                    Field.Index.NOT_ANALYZED,
                    Field.TermVector.NO);

                document.Add(hasNodeField);
                document.Add(nodeIdField);
                document.Add(nodeKeyField);
                document.Add(nodeTypeField);
                document.Add(nodeAliasField);

                if (publishedItemType == PublishedItemType.Content)
                {
                    var culture = indexingContext?.HostItem?.GetCulture() ?? indexingContext.Item.GetCulture();

                    if (culture != null)
                    {
                        var cultureField = new Field(
                            LookConstants.CultureField,
                            culture.LCID.ToString(),
                            Field.Store.NO,
                            Field.Index.NOT_ANALYZED,
                            Field.TermVector.NO);

                        document.Add(cultureField);
                    }
                }

                if (indexingContext.HostItem != null)
                {
                    var isDetachedField = new Field(
                        LookConstants.IsDetachedField,
                        "1",
                        Field.Store.NO,
                        Field.Index.NOT_ANALYZED);

                    // indexing detached item, so store the host context id so we can return the detached item
                    var hostIdField = new Field(
                        LookConstants.HostIdField,
                        indexingContext.HostItem.Id.ToString(),
                        Field.Store.YES,
                        Field.Index.NOT_ANALYZED);

                    document.Add(isDetachedField);
                    document.Add(hostIdField);
                }
            }

            if (LookService.Instance.NameIndexer != null)
            {
                string name = null;

                try
                {
                    name = LookService.Instance.NameIndexer(indexingContext);
                }
                catch (Exception exception)
                {
                    LogHelper.WarnWithException(typeof(LookService), "Error in name indexer", exception);
                }

                if (name != null)
                {
                    var hasNameField = new Field(
                        LookConstants.HasNameField,
                        "1",
                        Field.Store.NO,
                        Field.Index.NOT_ANALYZED);

                    var nameField = new Field(
                        LookConstants.NameField,
                        name,
                        Field.Store.YES,
                        Field.Index.NOT_ANALYZED,
                        Field.TermVector.YES);

                    // field for lower case searching
                    var nameFieldLowered = new Field(
                        LookConstants.NameField + "_Lowered",
                        name.ToLower(),
                        Field.Store.NO,
                        Field.Index.NOT_ANALYZED,
                        Field.TermVector.YES);

                    var nameSortedField = new Field(
                        LuceneIndexer.SortedFieldNamePrefix + LookConstants.NameField,
                        name.ToLower(),                         // force case insentive sorting
                        Field.Store.NO,
                        Field.Index.NOT_ANALYZED,
                        Field.TermVector.NO);

                    document.Add(hasNameField);
                    document.Add(nameField);
                    document.Add(nameFieldLowered);
                    document.Add(nameSortedField);
                }
            }

            if (LookService.Instance.DateIndexer != null)
            {
                DateTime?date = null;

                try
                {
                    date = LookService.Instance.DateIndexer(indexingContext);
                }
                catch (Exception exception)
                {
                    LogHelper.WarnWithException(typeof(LookService), "Error in date indexer", exception);
                }

                if (date != null)
                {
                    var hasDateField = new Field(
                        LookConstants.HasDateField,
                        "1",
                        Field.Store.NO,
                        Field.Index.NOT_ANALYZED);

                    var dateValue = DateTools.DateToString(date.Value, DateTools.Resolution.SECOND);

                    var dateField = new Field(
                        LookConstants.DateField,
                        dateValue,
                        Field.Store.YES,
                        Field.Index.ANALYZED,
                        Field.TermVector.YES);

                    var dateSortedField = new Field(
                        LuceneIndexer.SortedFieldNamePrefix + LookConstants.DateField,
                        dateValue,
                        Field.Store.NO,
                        Field.Index.NOT_ANALYZED,
                        Field.TermVector.NO);

                    document.Add(hasDateField);
                    document.Add(dateField);
                    document.Add(dateSortedField);
                }
            }

            if (LookService.Instance.TextIndexer != null)
            {
                string text = null;

                try
                {
                    text = LookService.Instance.TextIndexer(indexingContext);
                }
                catch (Exception exception)
                {
                    LogHelper.WarnWithException(typeof(LookService), "Error in text indexer", exception);
                }

                if (text != null)
                {
                    var hasTextField = new Field(
                        LookConstants.HasTextField,
                        "1",
                        Field.Store.NO,
                        Field.Index.NOT_ANALYZED);

                    var textField = new Field(
                        LookConstants.TextField,
                        text,
                        Field.Store.YES,
                        Field.Index.ANALYZED,
                        Field.TermVector.YES);

                    document.Add(hasTextField);
                    document.Add(textField);
                }
            }

            if (LookService.Instance.TagIndexer != null)
            {
                LookTag[] tags = null;

                try
                {
                    tags = LookService.Instance.TagIndexer(indexingContext);
                }
                catch (Exception exception)
                {
                    LogHelper.WarnWithException(typeof(LookService), "Error in tag indexer", exception);
                }

                if (tags != null)
                {
                    foreach (var tag in tags)
                    {
                        var hasTagsField = new Field(
                            LookConstants.HasTagsField,
                            "1",
                            Field.Store.NO,
                            Field.Index.NOT_ANALYZED);

                        // add all tags to a common field (serialized such that Tag objects can be restored from this)
                        var allTagsField = new Field(
                            LookConstants.AllTagsField,
                            tag.ToString(),
                            Field.Store.YES,
                            Field.Index.NOT_ANALYZED);

                        // add the tag value to a specific field - this is used for searching on
                        var tagField = new Field(
                            LookConstants.TagsField + tag.Group,
                            tag.Name,
                            Field.Store.YES,
                            Field.Index.NOT_ANALYZED);

                        document.Add(hasTagsField);
                        document.Add(allTagsField);
                        document.Add(tagField);
                    }
                }
            }

            if (LookService.Instance.LocationIndexer != null)
            {
                Location location = null;

                try
                {
                    location = LookService.Instance.LocationIndexer(indexingContext);
                }
                catch (Exception exception)
                {
                    LogHelper.WarnWithException(typeof(LookService), "Error in location indexer", exception);
                }

                if (location != null)
                {
                    var hasLocationField = new Field(
                        LookConstants.HasLocationField,
                        "1",
                        Field.Store.NO,
                        Field.Index.NOT_ANALYZED);

                    var locationField = new Field(
                        LookConstants.LocationField,
                        location.ToString(),
                        Field.Store.YES,
                        Field.Index.NOT_ANALYZED);

                    var locationLatitudeField = new Field(
                        LookConstants.LocationField + "_Latitude",
                        NumericUtils.DoubleToPrefixCoded(location.Latitude),
                        Field.Store.YES,
                        Field.Index.NOT_ANALYZED);

                    var locationLongitudeField = new Field(
                        LookConstants.LocationField + "_Longitude",
                        NumericUtils.DoubleToPrefixCoded(location.Longitude),
                        Field.Store.YES,
                        Field.Index.NOT_ANALYZED);

                    document.Add(hasLocationField);
                    document.Add(locationField);
                    document.Add(locationLatitudeField);
                    document.Add(locationLongitudeField);

                    foreach (var cartesianTierPlotter in LookService.Instance.CartesianTierPlotters)
                    {
                        var boxId = cartesianTierPlotter.GetTierBoxId(location.Latitude, location.Longitude);

                        var tierField = new Field(
                            cartesianTierPlotter.GetTierFieldName(),
                            NumericUtils.DoubleToPrefixCoded(boxId),
                            Field.Store.YES,
                            Field.Index.NOT_ANALYZED_NO_NORMS);

                        document.Add(tierField);
                    }
                }
            }
        }
Пример #21
0
        /// <summary>
        /// Perform a Look search
        /// </summary>
        /// <param name="lookQuery">A LookQuery model for the search criteria</param>
        /// <returns>A LookResult model for the search response</returns>
        public static LookResult Search(LookQuery lookQuery)
        {
            // flag to indicate whether there are any query clauses in the supplied LookQuery
            bool hasQuery = lookQuery?.Compiled != null ? true : false;

            if (lookQuery == null)
            {
                return(LookResult.Error("LookQuery object was null"));
            }

            if (lookQuery.SearchingContext == null) // supplied by unit test to skip examine dependency
            {
                // attempt to get searching context from examine searcher name
                lookQuery.SearchingContext = LookService.GetSearchingContext(lookQuery.SearcherName);

                if (lookQuery.SearchingContext == null)
                {
                    return(LookResult.Error("SearchingContext was null"));
                }
            }

            if (lookQuery.Compiled == null)
            {
                BooleanQuery query  = null; // the lucene query being built
                Filter       filter = null; // used for geospatial queries
                Sort         sort   = null;
                Func <string, IHtmlString> getHighlight = x => null;
                Func <int, double?>        getDistance  = x => null;

                query = new BooleanQuery();

                #region RawQuery

                if (!string.IsNullOrWhiteSpace(lookQuery.RawQuery))
                {
                    hasQuery = true;

                    query.Add(
                        new QueryParser(Lucene.Net.Util.Version.LUCENE_29, null, lookQuery.SearchingContext.Analyzer).Parse(lookQuery.RawQuery),
                        BooleanClause.Occur.MUST);
                }

                #endregion

                #region ExamineQuery

                if (lookQuery.ExamineQuery != null)
                {
                    var luceneSearchCriteria = lookQuery.ExamineQuery as LuceneSearchCriteria; // will be of type LookSearchCriteria when using the custom Look indexer/searcher

                    if (luceneSearchCriteria != null && luceneSearchCriteria.Query != null)
                    {
                        hasQuery = true;

                        query.Add(luceneSearchCriteria.Query, BooleanClause.Occur.MUST);
                    }
                }

                #endregion

                #region NodeQuery

                if (lookQuery.NodeQuery != null)
                {
                    hasQuery = true;

                    query.Add(new TermQuery(new Term(LookConstants.HasNodeField, "1")), BooleanClause.Occur.MUST);

                    // HasType
                    if (lookQuery.NodeQuery.Type != null)
                    {
                        query.Add(
                            new TermQuery(
                                new Term(LookConstants.NodeTypeField, lookQuery.NodeQuery.Type.ToString())),
                            BooleanClause.Occur.MUST);
                    }

                    // HasTypeAny
                    if (lookQuery.NodeQuery.TypeAny != null && lookQuery.NodeQuery.TypeAny.Any())
                    {
                        var nodeTypeQuery = new BooleanQuery();

                        foreach (var nodeType in lookQuery.NodeQuery.TypeAny)
                        {
                            nodeTypeQuery.Add(
                                new TermQuery(
                                    new Term(LookConstants.NodeTypeField, nodeType.ToString())),
                                BooleanClause.Occur.SHOULD);
                        }

                        query.Add(nodeTypeQuery, BooleanClause.Occur.MUST);
                    }

                    // Detached
                    switch (lookQuery.NodeQuery.DetachedQuery)
                    {
                    case DetachedQuery.ExcludeDetached:

                        query.Add(
                            new TermQuery(new Term(LookConstants.IsDetachedField, "1")),
                            BooleanClause.Occur.MUST_NOT);

                        break;

                    case DetachedQuery.OnlyDetached:

                        query.Add(
                            new TermQuery(new Term(LookConstants.IsDetachedField, "1")),
                            BooleanClause.Occur.MUST);

                        break;
                    }

                    // HasCulture
                    if (lookQuery.NodeQuery.Culture != null)
                    {
                        query.Add(
                            new TermQuery(
                                new Term(LookConstants.CultureField, lookQuery.NodeQuery.Culture.LCID.ToString())),
                            BooleanClause.Occur.MUST);
                    }

                    // HasCultureAny
                    if (lookQuery.NodeQuery.CultureAny != null && lookQuery.NodeQuery.CultureAny.Any())
                    {
                        var nodeCultureQuery = new BooleanQuery();

                        foreach (var nodeCulture in lookQuery.NodeQuery.CultureAny)
                        {
                            nodeCultureQuery.Add(
                                new TermQuery(
                                    new Term(LookConstants.CultureField, nodeCulture.LCID.ToString())),
                                BooleanClause.Occur.SHOULD);
                        }

                        query.Add(nodeCultureQuery, BooleanClause.Occur.MUST);
                    }

                    // HasAlias
                    if (lookQuery.NodeQuery.Alias != null)
                    {
                        query.Add(
                            new TermQuery(
                                new Term(LookConstants.NodeAliasField, lookQuery.NodeQuery.Alias.ToString())),
                            BooleanClause.Occur.MUST);
                    }

                    // HasAliasAny
                    if (lookQuery.NodeQuery.AliasAny != null && lookQuery.NodeQuery.AliasAny.Any())
                    {
                        var nodeAliasQuery = new BooleanQuery();

                        foreach (var typeAlias in lookQuery.NodeQuery.AliasAny)
                        {
                            nodeAliasQuery.Add(
                                new TermQuery(
                                    new Term(LookConstants.NodeAliasField, typeAlias)),
                                BooleanClause.Occur.SHOULD);
                        }

                        query.Add(nodeAliasQuery, BooleanClause.Occur.MUST);
                    }

                    // Ids
                    if (lookQuery.NodeQuery.Ids != null && lookQuery.NodeQuery.Ids.Any())
                    {
                        if (lookQuery.NodeQuery.NotIds != null)
                        {
                            var conflictIds = lookQuery.NodeQuery.Ids.Where(x => lookQuery.NodeQuery.NotIds.Contains(x));

                            if (conflictIds.Any())
                            {
                                return(LookResult.Error($"Conflict in NodeQuery, Ids: '{ string.Join(",", conflictIds) }' are in both Ids and NotIds"));
                            }
                        }

                        var idQuery = new BooleanQuery();

                        foreach (var id in lookQuery.NodeQuery.Ids)
                        {
                            idQuery.Add(
                                new TermQuery(new Term(LookConstants.NodeIdField, id.ToString())),
                                BooleanClause.Occur.SHOULD);
                        }

                        query.Add(idQuery, BooleanClause.Occur.MUST);
                    }

                    // Keys
                    if (lookQuery.NodeQuery.Keys != null && lookQuery.NodeQuery.Keys.Any())
                    {
                        if (lookQuery.NodeQuery.NotKeys != null)
                        {
                            var conflictKeys = lookQuery.NodeQuery.Keys.Where(x => lookQuery.NodeQuery.NotKeys.Contains(x));

                            if (conflictKeys.Any())
                            {
                                return(LookResult.Error($"Conflict in NodeQuery, keys: '{ string.Join(",", conflictKeys) }' are in both Keys and NotKeys"));
                            }
                        }

                        var keyQuery = new BooleanQuery();

                        foreach (var key in lookQuery.NodeQuery.Keys)
                        {
                            keyQuery.Add(
                                new TermQuery(new Term(LookConstants.NodeKeyField, key.GuidToLuceneString())),
                                BooleanClause.Occur.SHOULD);
                        }

                        query.Add(keyQuery, BooleanClause.Occur.MUST);
                    }

                    // NotId
                    if (lookQuery.NodeQuery.NotId != null)
                    {
                        query.Add(
                            new TermQuery(new Term(LookConstants.NodeIdField, lookQuery.NodeQuery.NotId.ToString())),
                            BooleanClause.Occur.MUST_NOT);
                    }

                    // NotIds
                    if (lookQuery.NodeQuery.NotIds != null && lookQuery.NodeQuery.NotIds.Any())
                    {
                        foreach (var exculudeId in lookQuery.NodeQuery.NotIds)
                        {
                            query.Add(
                                new TermQuery(new Term(LookConstants.NodeIdField, exculudeId.ToString())),
                                BooleanClause.Occur.MUST_NOT);
                        }
                    }

                    // NotKey
                    if (lookQuery.NodeQuery.NotKey != null)
                    {
                        query.Add(
                            new TermQuery(new Term(LookConstants.NodeKeyField, lookQuery.NodeQuery.NotKey.ToString())),
                            BooleanClause.Occur.MUST_NOT);
                    }

                    // NotKeys
                    if (lookQuery.NodeQuery.NotKeys != null && lookQuery.NodeQuery.NotKeys.Any())
                    {
                        foreach (var excludeKey in lookQuery.NodeQuery.NotKeys)
                        {
                            query.Add(
                                new TermQuery(new Term(LookConstants.NodeKeyField, excludeKey.GuidToLuceneString())),
                                BooleanClause.Occur.MUST_NOT);
                        }
                    }
                }

                #endregion

                #region NameQuery

                if (lookQuery.NameQuery != null)
                {
                    hasQuery = true;

                    query.Add(new TermQuery(new Term(LookConstants.HasNameField, "1")), BooleanClause.Occur.MUST);

                    string wildcard1 = null;
                    string wildcard2 = null; // incase Contains specified with StartsWith and/or EndsWith

                    if (!string.IsNullOrEmpty(lookQuery.NameQuery.StartsWith))
                    {
                        if (!string.IsNullOrEmpty(lookQuery.NameQuery.Is))
                        {
                            if (!lookQuery.NameQuery.Is.StartsWith(lookQuery.NameQuery.StartsWith))
                            {
                                return(LookResult.Error("Conflict in NameQuery between Is and StartsWith"));
                            }
                        }
                        else
                        {
                            wildcard1 = lookQuery.NameQuery.StartsWith + "*";
                        }
                    }

                    if (!string.IsNullOrEmpty(lookQuery.NameQuery.EndsWith))
                    {
                        if (!string.IsNullOrEmpty(lookQuery.NameQuery.Is))
                        {
                            if (!lookQuery.NameQuery.Is.EndsWith(lookQuery.NameQuery.EndsWith))
                            {
                                return(LookResult.Error("Conflict in NameQuery between Is and EndsWith"));
                            }
                        }
                        else
                        {
                            if (wildcard1 == null)
                            {
                                wildcard1 = "*" + lookQuery.NameQuery.EndsWith;
                            }
                            else
                            {
                                wildcard1 += lookQuery.NameQuery.EndsWith;
                            }
                        }
                    }

                    if (!string.IsNullOrEmpty(lookQuery.NameQuery.Contains))
                    {
                        if (!string.IsNullOrEmpty(lookQuery.NameQuery.Is))
                        {
                            if (!lookQuery.NameQuery.Is.Contains(lookQuery.NameQuery.Contains))
                            {
                                return(LookResult.Error("Conflict in NameQuery between Is and Contains"));
                            }
                        }
                        else
                        {
                            if (wildcard1 == null)
                            {
                                wildcard1 = "*" + lookQuery.NameQuery.Contains + "*";
                            }
                            else
                            {
                                wildcard2 = "*" + lookQuery.NameQuery.Contains + "*";
                            }
                        }
                    }

                    var nameField = lookQuery.NameQuery.CaseSensitive ? LookConstants.NameField : LookConstants.NameField + "_Lowered";

                    if (wildcard1 != null)
                    {
                        var wildcard = lookQuery.NameQuery.CaseSensitive ? wildcard1 : wildcard1.ToLower();

                        query.Add(new WildcardQuery(new Term(nameField, wildcard)), BooleanClause.Occur.MUST);

                        if (wildcard2 != null)
                        {
                            wildcard = lookQuery.NameQuery.CaseSensitive ? wildcard2 : wildcard2.ToLower();

                            query.Add(new WildcardQuery(new Term(nameField, wildcard)), BooleanClause.Occur.MUST);
                        }
                    }

                    if (!string.IsNullOrEmpty(lookQuery.NameQuery.Is))
                    {
                        var isText = lookQuery.NameQuery.CaseSensitive ? lookQuery.NameQuery.Is : lookQuery.NameQuery.Is.ToLower();

                        query.Add(new TermQuery(new Term(nameField, isText)), BooleanClause.Occur.MUST);
                    }
                }

                #endregion

                #region DateQuery

                if (lookQuery.DateQuery != null)
                {
                    hasQuery = true;

                    query.Add(new TermQuery(new Term(LookConstants.HasDateField, "1")), BooleanClause.Occur.MUST);

                    if (lookQuery.DateQuery.After.HasValue || lookQuery.DateQuery.Before.HasValue)
                    {
                        var includeLower = lookQuery.DateQuery.After == null || lookQuery.DateQuery.Boundary == DateBoundary.Inclusive || lookQuery.DateQuery.Boundary == DateBoundary.BeforeExclusiveAfterInclusive;
                        var includeUpper = lookQuery.DateQuery.Before == null || lookQuery.DateQuery.Boundary == DateBoundary.Inclusive || lookQuery.DateQuery.Boundary == DateBoundary.BeforeInclusiveAfterExclusive;

                        query.Add(
                            new TermRangeQuery(
                                LookConstants.DateField,
                                lookQuery.DateQuery.After.DateToLuceneString() ?? DateTime.MinValue.DateToLuceneString(),
                                lookQuery.DateQuery.Before.DateToLuceneString() ?? DateTime.MaxValue.DateToLuceneString(),
                                includeLower,
                                includeUpper),
                            BooleanClause.Occur.MUST);
                    }
                }

                #endregion

                #region TextQuery

                if (lookQuery.TextQuery != null)
                {
                    hasQuery = true;

                    query.Add(new TermQuery(new Term(LookConstants.HasTextField, "1")), BooleanClause.Occur.MUST);

                    if (!string.IsNullOrWhiteSpace(lookQuery.TextQuery.SearchText))
                    {
                        var queryParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, LookConstants.TextField, lookQuery.SearchingContext.Analyzer);

                        Query searchTextQuery = null;

                        try
                        {
                            searchTextQuery = queryParser.Parse(lookQuery.TextQuery.SearchText);
                        }
                        catch
                        {
                            return(LookResult.Error($"Unable to parse LookQuery.TextQuery.SearchText: '{ lookQuery.TextQuery.SearchText }' into a Lucene query"));
                        }

                        if (searchTextQuery != null)
                        {
                            query.Add(searchTextQuery, BooleanClause.Occur.MUST);

                            if (lookQuery.TextQuery.GetHighlight)
                            {
                                var queryScorer = new QueryScorer(searchTextQuery.Rewrite(lookQuery.SearchingContext.IndexSearcher.GetIndexReader()));

                                var highlighter = new Highlighter(new SimpleHTMLFormatter("<strong>", "</strong>"), queryScorer);

                                getHighlight = (x) =>
                                {
                                    var tokenStream = lookQuery.SearchingContext.Analyzer.TokenStream(LookConstants.TextField, new StringReader(x));

                                    var highlight = highlighter.GetBestFragments(
                                        tokenStream,
                                        x,
                                        1,                             // max number of fragments
                                        "...");

                                    return(new HtmlString(highlight));
                                };
                            }
                        }
                    }
                }

                #endregion

                #region TagQuery

                if (lookQuery.TagQuery != null)
                {
                    hasQuery = true;

                    query.Add(new TermQuery(new Term(LookConstants.HasTagsField, "1")), BooleanClause.Occur.MUST);

                    // Has
                    if (lookQuery.TagQuery.Has != null)
                    {
                        query.Add(
                            new TermQuery(new Term(LookConstants.TagsField + lookQuery.TagQuery.Has.Group, lookQuery.TagQuery.Has.Name)),
                            BooleanClause.Occur.MUST);
                    }

                    // Not
                    if (lookQuery.TagQuery.Not != null)
                    {
                        query.Add(
                            new TermQuery(new Term(LookConstants.TagsField + lookQuery.TagQuery.Not.Group, lookQuery.TagQuery.Not.Name)),
                            BooleanClause.Occur.MUST_NOT);
                    }

                    // HasAll
                    if (lookQuery.TagQuery.HasAll != null && lookQuery.TagQuery.HasAll.Any())
                    {
                        foreach (var tag in lookQuery.TagQuery.HasAll)
                        {
                            query.Add(
                                new TermQuery(new Term(LookConstants.TagsField + tag.Group, tag.Name)),
                                BooleanClause.Occur.MUST);
                        }
                    }

                    // HasAllOr
                    if (lookQuery.TagQuery.HasAllOr != null && lookQuery.TagQuery.HasAllOr.Any() && lookQuery.TagQuery.HasAllOr.SelectMany(x => x).Any())
                    {
                        var orQuery = new BooleanQuery();

                        foreach (var tagCollection in lookQuery.TagQuery.HasAllOr)
                        {
                            if (tagCollection.Any())
                            {
                                var allTagQuery = new BooleanQuery();

                                foreach (var tag in tagCollection)
                                {
                                    allTagQuery.Add(
                                        new TermQuery(new Term(LookConstants.TagsField + tag.Group, tag.Name)),
                                        BooleanClause.Occur.MUST);
                                }

                                orQuery.Add(allTagQuery, BooleanClause.Occur.SHOULD);
                            }
                        }

                        query.Add(orQuery, BooleanClause.Occur.MUST);
                    }

                    // HasAny
                    if (lookQuery.TagQuery.HasAny != null && lookQuery.TagQuery.HasAny.Any())
                    {
                        var anyTagQuery = new BooleanQuery();

                        foreach (var tag in lookQuery.TagQuery.HasAny)
                        {
                            anyTagQuery.Add(
                                new TermQuery(new Term(LookConstants.TagsField + tag.Group, tag.Name)),
                                BooleanClause.Occur.SHOULD);
                        }

                        query.Add(anyTagQuery, BooleanClause.Occur.MUST);
                    }

                    // HasAnyAnd
                    if (lookQuery.TagQuery.HasAnyAnd != null && lookQuery.TagQuery.HasAnyAnd.Any())
                    {
                        foreach (var tagCollection in lookQuery.TagQuery.HasAnyAnd)
                        {
                            if (tagCollection.Any())
                            {
                                var anyTagQuery = new BooleanQuery();

                                foreach (var tag in tagCollection)
                                {
                                    anyTagQuery.Add(
                                        new TermQuery(new Term(LookConstants.TagsField + tag.Group, tag.Name)),
                                        BooleanClause.Occur.SHOULD);
                                }

                                query.Add(anyTagQuery, BooleanClause.Occur.MUST);
                            }
                        }
                    }

                    // NotAny
                    if (lookQuery.TagQuery.NotAny != null && lookQuery.TagQuery.NotAny.Any())
                    {
                        foreach (var tag in lookQuery.TagQuery.NotAny)
                        {
                            query.Add(
                                new TermQuery(new Term(LookConstants.TagsField + tag.Group, tag.Name)),
                                BooleanClause.Occur.MUST_NOT);
                        }
                    }
                }

                #endregion

                #region LocationQuery

                if (lookQuery.LocationQuery != null)
                {
                    hasQuery = true;

                    query.Add(new TermQuery(new Term(LookConstants.HasLocationField, "1")), BooleanClause.Occur.MUST);

                    if (lookQuery.LocationQuery.Boundary != null) // limit results within an lat lng fixed view (eg, typical map bounds)
                    {
                        query.Add(
                            new TermRangeQuery(
                                LookConstants.LocationField + "_Latitude",
                                NumericUtils.DoubleToPrefixCoded(lookQuery.LocationQuery.Boundary.LatitudeMin),
                                NumericUtils.DoubleToPrefixCoded(lookQuery.LocationQuery.Boundary.LatitudeMax),
                                true,
                                true),
                            BooleanClause.Occur.MUST);

                        query.Add(
                            new TermRangeQuery(
                                LookConstants.LocationField + "_Longitude",
                                NumericUtils.DoubleToPrefixCoded(lookQuery.LocationQuery.Boundary.LongitudeMin),
                                NumericUtils.DoubleToPrefixCoded(lookQuery.LocationQuery.Boundary.LongitudeMax),
                                true,
                                true),
                            BooleanClause.Occur.MUST);
                    }

                    if (lookQuery.LocationQuery.Location != null) // location set, so can calculate distance
                    {
                        double maxDistance = LookService._maxDistance;

                        if (lookQuery.LocationQuery.MaxDistance != null)
                        {
                            maxDistance = Math.Min(lookQuery.LocationQuery.MaxDistance.GetMiles(), maxDistance);
                        }

                        var distanceQueryBuilder = new DistanceQueryBuilder(
                            lookQuery.LocationQuery.Location.Latitude,
                            lookQuery.LocationQuery.Location.Longitude,
                            maxDistance,
                            LookConstants.LocationField + "_Latitude",
                            LookConstants.LocationField + "_Longitude",
                            LookConstants.LocationTierFieldPrefix,
                            true);

                        filter = distanceQueryBuilder.Filter;

                        if (lookQuery.SortOn == SortOn.Distance)
                        {
                            sort = new Sort(
                                new SortField(
                                    LookConstants.DistanceField,
                                    new DistanceFieldComparatorSource(distanceQueryBuilder.DistanceFilter)));
                        }

                        getDistance = new Func <int, double?>(x =>
                        {
                            if (distanceQueryBuilder.DistanceFilter.Distances.ContainsKey(x))
                            {
                                return(distanceQueryBuilder.DistanceFilter.Distances[x]);
                            }

                            return(null);
                        });
                    }
                }

                #endregion

                if (hasQuery)
                {
                    switch (lookQuery.SortOn)
                    {
                    case SortOn.Name:     // a -> z
                        sort = new Sort(new SortField(LuceneIndexer.SortedFieldNamePrefix + LookConstants.NameField, SortField.STRING));
                        break;

                    case SortOn.DateAscending:     // oldest -> newest
                        sort = new Sort(new SortField(LuceneIndexer.SortedFieldNamePrefix + LookConstants.DateField, SortField.LONG, false));
                        break;

                    case SortOn.DateDescending:     // newest -> oldest
                        sort = new Sort(new SortField(LuceneIndexer.SortedFieldNamePrefix + LookConstants.DateField, SortField.LONG, true));
                        break;

                        // SortOn.Distance already set (if valid)
                    }

                    lookQuery.Compiled = new LookQueryCompiled(
                        lookQuery,
                        query,
                        filter,
                        sort ?? new Sort(SortField.FIELD_SCORE),
                        getHighlight,
                        getDistance);
                }
            }

            if (!hasQuery)
            {
                return(LookResult.Error("No query clauses supplied")); // empty failure
            }

            TopDocs topDocs = lookQuery
                              .SearchingContext
                              .IndexSearcher
                              .Search(
                lookQuery.Compiled.Query,
                lookQuery.Compiled.Filter,
                LookService._maxLuceneResults,
                lookQuery.Compiled.Sort);

            if (topDocs.TotalHits > 0)
            {
                List <Facet> facets = null;

                if (lookQuery.TagQuery != null && lookQuery.TagQuery.FacetOn != null)
                {
                    facets = new List <Facet>();

                    Query facetQuery = lookQuery.Compiled.Filter != null
                                            ? (Query) new FilteredQuery(lookQuery.Compiled.Query, lookQuery.Compiled.Filter)
                                            : lookQuery.Compiled.Query;

                    // do a facet query for each group in the array
                    foreach (var group in lookQuery.TagQuery.FacetOn.TagGroups)
                    {
                        var simpleFacetedSearch = new SimpleFacetedSearch(
                            lookQuery.SearchingContext.IndexSearcher.GetIndexReader(),
                            LookConstants.TagsField + group);

                        var facetResult = simpleFacetedSearch.Search(facetQuery);

                        facets.AddRange(
                            facetResult
                            .HitsPerFacet
                            .Select(
                                x => new Facet()
                        {
                            Tags  = new LookTag[] { new LookTag(group, x.Name.ToString()) },
                            Count = Convert.ToInt32(x.HitCount)
                        }
                                ));
                    }
                }

                return(new LookResult(
                           lookQuery,
                           topDocs,
                           facets != null ? facets.ToArray() : new Facet[] { }));
            }

            return(LookResult.Empty()); // empty success
        }
        private static void IndexLocation(IndexingContext indexingContext, Document document)
        {
            if (indexingContext.Cancelled)
            {
                return;
            }

            var locationIndexer = LookService.GetLocationIndexer(indexingContext.IndexerName);

            if (locationIndexer != null)
            {
                Location location = null;

                try
                {
                    location = locationIndexer(indexingContext);
                }
                catch (Exception exception)
                {
                    LogHelper.WarnWithException(typeof(LookService), "Error in location indexer", exception);
                }

                if (location != null)
                {
                    var hasLocationField = new Field(
                        LookConstants.HasLocationField,
                        "1",
                        Field.Store.NO,
                        Field.Index.NOT_ANALYZED);

                    var locationField = new Field(
                        LookConstants.LocationField,
                        location.ToString(),
                        Field.Store.YES,
                        Field.Index.NOT_ANALYZED);

                    var locationLatitudeField = new Field(
                        LookConstants.LocationField + "_Latitude",
                        NumericUtils.DoubleToPrefixCoded(location.Latitude),
                        Field.Store.YES,
                        Field.Index.NOT_ANALYZED);

                    var locationLongitudeField = new Field(
                        LookConstants.LocationField + "_Longitude",
                        NumericUtils.DoubleToPrefixCoded(location.Longitude),
                        Field.Store.YES,
                        Field.Index.NOT_ANALYZED);

                    document.Add(hasLocationField);
                    document.Add(locationField);
                    document.Add(locationLatitudeField);
                    document.Add(locationLongitudeField);

                    foreach (var cartesianTierPlotter in LookService.Instance._cartesianTierPlotters)
                    {
                        var boxId = cartesianTierPlotter.GetTierBoxId(location.Latitude, location.Longitude);

                        var tierField = new Field(
                            cartesianTierPlotter.GetTierFieldName(),
                            NumericUtils.DoubleToPrefixCoded(boxId),
                            Field.Store.YES,
                            Field.Index.NOT_ANALYZED_NO_NORMS);

                        document.Add(tierField);
                    }
                }
            }
        }
        private string GetTermText(Term term)
        {
            var fieldName = term.Field();
            var fieldText = term.Text();

            if (fieldText == null)
            {
                return(null);
            }

            var fieldType = default(IndexValueType);

            if (!(LuceneSearchManager?.IndexFieldTypeInfo?.TryGetValue(fieldName, out fieldType) ?? false))
            {
                switch (fieldName)
                {
                case "NodeTimestamp":
                case "VersionTimestamp":
                    fieldType = IndexValueType.Long;
                    break;

                default:
                    var c = fieldText.ToCharArray();
                    for (var i = 0; i < c.Length; i++)
                    {
                        if (c[i] < ' ')
                        {
                            c[i] = '.';
                        }
                    }
                    return(new string(c));
                }
            }

            var pt = Providers.Instance.StorageSchema.PropertyTypes[fieldName];

            if (pt == null)
            {
                switch (fieldName)
                {
                case "CreatedBy":
                case "ModifiedBy":
                case "Owner":
                case "VersionCreatedBy":
                case "VersionModifiedBy":
                case "Workspace":
                    fieldType = IndexValueType.Int;
                    break;
                    //case "NodeTimestamp":
                    //case "VersionTimestamp":
                    //    fieldType = IndexValueType.Long;
                    //    break;
                }
            }
            else
            {
                if (pt.DataType == DataType.Reference)
                {
                    fieldType = IndexValueType.Int;
                }
            }

            string check;

            switch (fieldType)
            {
            case IndexValueType.Bool:
            case IndexValueType.String:
            case IndexValueType.StringArray:
                return(fieldText);

            case IndexValueType.Int:
                var intValue = NumericUtils.PrefixCodedToInt(fieldText);
                check = NumericUtils.IntToPrefixCoded(intValue);
                if (check != fieldText)
                {
                    return(null);
                }
                return(Convert.ToString(intValue, CultureInfo.InvariantCulture));

            case IndexValueType.Long:
                var longValue = NumericUtils.PrefixCodedToLong(fieldText);
                check = NumericUtils.LongToPrefixCoded(longValue);
                if (check != fieldText)
                {
                    return(null);
                }
                return(Convert.ToString(longValue, CultureInfo.InvariantCulture));

            case IndexValueType.Float:
                var floatValue = NumericUtils.PrefixCodedToFloat(fieldText);
                check = NumericUtils.FloatToPrefixCoded(floatValue);
                if (check != fieldText)
                {
                    return(null);
                }
                return(Convert.ToString(floatValue, CultureInfo.InvariantCulture));

            case IndexValueType.Double:
                var doubleValue = NumericUtils.PrefixCodedToDouble(fieldText);
                check = NumericUtils.DoubleToPrefixCoded(doubleValue);
                if (check != fieldText)
                {
                    return(null);
                }
                return(Convert.ToString(doubleValue, CultureInfo.InvariantCulture));

            case IndexValueType.DateTime:
                var ticksValue = NumericUtils.PrefixCodedToLong(fieldText);
                check = NumericUtils.LongToPrefixCoded(ticksValue);
                if (check != fieldText)
                {
                    return(null);
                }
                var d = new DateTime(ticksValue);
                if (d.Hour == 0 && d.Minute == 0 && d.Second == 0)
                {
                    return(d.ToString("yyyy-MM-dd"));
                }
                if (d.Second == 0)
                {
                    return(d.ToString("yyyy-MM-dd HH:mm"));
                }
                return(d.ToString("yyyy-MM-dd HH:mm:ss"));

            default:
                throw new NotSupportedException("Unknown IndexFieldType: " + fieldType);
            }
        }
Пример #24
0
        /// <summary>
        /// Used to create the additional search fields
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        internal static void DocumentWriting(object sender, DocumentWritingEventArgs e)
        {
            if (e.Fields.ContainsKey(LookService.DateField)) // it's storing a date value as a long type
            {
                if (long.TryParse(e.Fields[LookService.DateField], out long ticks))
                {
                    e.Document.RemoveFields(LookService.DateField);

                    var dateField = new NumericField(
                        LookService.DateField,
                        Field.Store.YES,
                        false)
                                    .SetLongValue(ticks);

                    var dateSortedField = new NumericField(
                        LuceneIndexer.SortedFieldNamePrefix + LookService.DateField,
                        Field.Store.NO,                     //we don't want to store the field because we're only using it to sort, not return data
                        true)
                                          .SetLongValue(ticks);

                    e.Document.Add(dateField);
                    e.Document.Add(dateSortedField);
                }
            }

            if (e.Fields.ContainsKey(LookService.NameField))
            {
                var name = e.Fields[LookService.NameField];

                e.Document.RemoveFields(LookService.NameField);

                var nameField = new Field(
                    LookService.NameField,
                    name,
                    Field.Store.YES,
                    Field.Index.NOT_ANALYZED,
                    Field.TermVector.YES);

                var nameSortedField = new Field(
                    LuceneIndexer.SortedFieldNamePrefix + LookService.NameField,
                    name.ToLower(),
                    Field.Store.NO,
                    Field.Index.NOT_ANALYZED,
                    Field.TermVector.NO);

                e.Document.Add(nameField);
                e.Document.Add(nameSortedField);
            }

            if (e.Fields.ContainsKey(LookService.LocationField))
            {
                var location = new Location(e.Fields[LookService.LocationField]);

                var locationLatitudeField = new Field(
                    LookService.LocationField + "_Latitude",
                    NumericUtils.DoubleToPrefixCoded(location.Latitude),
                    Field.Store.YES,
                    Field.Index.NOT_ANALYZED);

                var locationLongitudeField = new Field(
                    LookService.LocationField + "_Longitude",
                    NumericUtils.DoubleToPrefixCoded(location.Longitude),
                    Field.Store.YES,
                    Field.Index.NOT_ANALYZED);


                e.Document.Add(locationLatitudeField);
                e.Document.Add(locationLongitudeField);

                foreach (var cartesianTierPlotter in LookService.Instance.CartesianTierPlotters)
                {
                    var boxId = cartesianTierPlotter.GetTierBoxId(location.Latitude, location.Longitude);

                    var tierField = new Field(
                        cartesianTierPlotter.GetTierFieldName(),
                        NumericUtils.DoubleToPrefixCoded(boxId),
                        Field.Store.YES,
                        Field.Index.NOT_ANALYZED_NO_NORMS);

                    e.Document.Add(tierField);
                }
            }
        }