Exemplo n.º 1
0
        public bool IsSame(string name, Field.Index?index, Field.Store store, Field.TermVector termVector, List <int> multipleItemsSameField)
        {
            // We are thinking it is possible to have collisions. This may not be true ever!
            if (_index != index || _store != store || _termVector != termVector || !string.Equals(_name, name))
            {
                return(false);
            }

            if (_multipleItemsSameField.Length != multipleItemsSameField.Count)
            {
                return(false);
            }

            int  count  = _multipleItemsSameField.Length;
            bool result = true;

            for (int i = 0; i < count; i++)
            {
                if (_multipleItemsSameField[i] != multipleItemsSameField[i])
                {
                    result = false;
                    break;
                }
            }

            return(result);
        }
Exemplo n.º 2
0
		public static Field.Index GetIndex(this IndexDefinition self, string name, Field.Index? defaultIndex)
		{
			if (self.Indexes == null)
				return defaultIndex ?? Field.Index.ANALYZED_NO_NORMS;
			FieldIndexing value;
			if (self.Indexes.TryGetValue(name, out value) == false)
			{
				if (self.Indexes.TryGetValue(Constants.AllFields, out value) == false)
				{
					string ignored;
					if (self.Analyzers.TryGetValue(name, out ignored) ||
						self.Analyzers.TryGetValue(Constants.AllFields, out ignored))
					{
						return Field.Index.ANALYZED; // if there is a custom analyzer, the value should be analyzed
					}
					return defaultIndex ?? Field.Index.ANALYZED_NO_NORMS;
				}
			}
			switch (value)
			{
				case FieldIndexing.No:
					return Field.Index.NO;
				case FieldIndexing.Analyzed:
					return Field.Index.ANALYZED_NO_NORMS;
				case FieldIndexing.NotAnalyzed:
					return Field.Index.NOT_ANALYZED_NO_NORMS;
				case FieldIndexing.Default:
					return defaultIndex ?? Field.Index.ANALYZED_NO_NORMS;
				default:
					throw new ArgumentOutOfRangeException();
			}
		}
Exemplo n.º 3
0
        public bool IsSame(string name, Field.Index?index, Field.Store store, Field.TermVector termVector, int[] multipleItemsSameField)
        {
            // We are thinking it is possible to have collisions. This may not be true ever!
            if (_index != index || _store != store || _termVector != termVector || !string.Equals(_name, name))
            {
                return(false);
            }

            if (_multipleItemsSameField.Length != multipleItemsSameField.Length)
            {
                return(false);
            }

            // PERF: In this case we don't cache the length to allow the JIT to figure out it can evict the bound checks.
            bool result = true;

            for (int i = 0; i < _multipleItemsSameField.Length; i++)
            {
                if (_multipleItemsSameField[i] != multipleItemsSameField[i])
                {
                    result = false;
                    break;
                }
            }

            return(result);
        }
Exemplo n.º 4
0
 public FieldCacheKey(string name, Field.Index?index, Field.Store store, int[] multipleItemsSameField)
 {
     this.name  = name;
     this.index = index;
     this.store = store;
     this.multipleItemsSameField = multipleItemsSameField;
 }
Exemplo n.º 5
0
 public FieldCacheKey(string name, Field.Index?index, Field.Store store, Field.TermVector termVector, int[] multipleItemsSameField)
 {
     _name                   = name;
     _index                  = index;
     _store                  = store;
     _termVector             = termVector;
     _multipleItemsSameField = multipleItemsSameField;
 }
Exemplo n.º 6
0
            public FieldCacheKey(string name, Field.Index?index, Field.Store store, Field.TermVector termVector, int[] multipleItemsSameField)
            {
                this.name                   = name;
                this.index                  = index;
                this.store                  = store;
                this.termVector             = termVector;
                this.multipleItemsSameField = multipleItemsSameField;

                this.HashKey = new Lazy <int>(CalculateHashCode);
            }
Exemplo n.º 7
0
        public static int CalculateHashCode(string name, Field.Index?index, Field.Store store, Field.TermVector termVector, int[] multipleItemsSameField)
        {
            ulong tmpHash = Hashing.Marvin32.CalculateInline(name) << 32;
            int   field   = ((index != null ? (byte)index : 0xFF) << 16 | ((byte)store << 8) | (byte)termVector);

            tmpHash = tmpHash | (uint)field;

            uint hash = Hashing.Mix(tmpHash);

            if (multipleItemsSameField.Length == 0)
            {
                return((int)hash);
            }

            return((int)Hashing.Combine(hash, Hashing.Marvin32.CalculateInline(multipleItemsSameField)));
        }
Exemplo n.º 8
0
        public Field.Index GetIndex(string name, Field.Index?defaultIndex)
        {
            var self = this;

            if (self.Indexes == null)
            {
                return(defaultIndex ?? Field.Index.ANALYZED_NO_NORMS);
            }
            FieldIndexing value;

            if (self.Indexes.TryGetValue(name, out value) == false)
            {
                if (self.Indexes.TryGetValue("__all_fields", out value) == false)
                {
                    string ignored;
                    if (self.Analyzers.TryGetValue(name, out ignored) ||
                        self.Analyzers.TryGetValue("__all_fields", out ignored))
                    {
                        return(Field.Index.ANALYZED); // if there is a custom analyzer, the value should be analyzed
                    }
                    return(defaultIndex ?? Field.Index.ANALYZED_NO_NORMS);
                }
            }
            switch (value)
            {
            case FieldIndexing.No:
                return(Field.Index.NO);

            case FieldIndexing.Analyzed:
                return(Field.Index.ANALYZED_NO_NORMS);

            case FieldIndexing.NotAnalyzed:
                return(Field.Index.NOT_ANALYZED_NO_NORMS);

            case FieldIndexing.Default:
                return(defaultIndex ?? Field.Index.ANALYZED_NO_NORMS);

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// This method generate the fields for indexing documents in lucene from the values.
        /// Given a name and a value, it has the following behavior:
        /// * If the value is enumerable, index all the items in the enumerable under the same field name
        /// * If the value is null, create a single field with the supplied name with the unanalyzed value 'NULL_VALUE'
        /// * If the value is string or was set to not analyzed, create a single field with the supplied name
        /// * If the value is date, create a single field with millisecond precision with the supplied name
        /// * If the value is numeric (int, long, double, decimal, or float) will create two fields:
        ///		1. with the supplied name, containing the numeric value as an unanalyzed string - useful for direct queries
        ///		2. with the name: name +'_Range', containing the numeric value in a form that allows range queries
        /// </summary>
        public IEnumerable <AbstractField> CreateFields(string name, object value, Field.Store defaultStorage, bool nestedArray = false, Field.TermVector defaultTermVector = Field.TermVector.NO, Field.Index?analyzed = null)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException("Field must be not null, not empty and cannot contain whitespace", "name");
            }

            if (char.IsLetter(name[0]) == false && name[0] != '_')
            {
                name = "_" + name;
            }

            if (viewGenerator.IsSpatialField(name))
            {
                return(viewGenerator.GetSpatialField(name).CreateIndexableFields(value));
            }

            return(CreateRegularFields(name, value, defaultStorage, nestedArray, defaultTermVector, analyzed));
        }
Exemplo n.º 10
0
        private IEnumerable <AbstractField> CreateRegularFields(string name, object value, Field.Store defaultStorage, bool nestedArray = false, Field.TermVector defaultTermVector = Field.TermVector.NO, Field.Index?analyzed = null)
        {
            var fieldIndexingOptions = analyzed ?? indexDefinition.GetIndex(name, null);
            var storage    = indexDefinition.GetStorage(name, defaultStorage);
            var termVector = indexDefinition.GetTermVector(name, defaultTermVector);

            if (fieldIndexingOptions == Field.Index.NO && storage == Field.Store.NO && termVector == Field.TermVector.NO)
            {
                yield break;
            }

            if (fieldIndexingOptions == Field.Index.NO && storage == Field.Store.NO)
            {
                fieldIndexingOptions = Field.Index.ANALYZED; // we have some sort of term vector, forcing index to be analyzed, then.
            }

            if (value == null)
            {
                yield return(CreateFieldWithCaching(name, Constants.NullValue, storage, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO));

                yield break;
            }

            CheckIfSortOptionsAndInputTypeMatch(name, value);

            var attachmentFoIndexing = value as AttachmentForIndexing;

            if (attachmentFoIndexing != null)
            {
                if (database == null)
                {
                    throw new InvalidOperationException(
                              "Cannot use attachment for indexing if the database parameter is null. This is probably a RavenDB bug");
                }

                var attachment = database.Attachments.GetStatic(attachmentFoIndexing.Key);
                if (attachment == null)
                {
                    yield break;
                }

                var fieldWithCaching = CreateFieldWithCaching(name, string.Empty, Field.Store.NO, fieldIndexingOptions, termVector);

                if (database.TransactionalStorage.IsAlreadyInBatch)
                {
                    var streamReader = new StreamReader(attachment.Data());
                    fieldWithCaching.SetValue(streamReader);
                }
                else
                {
                    // we are not in batch operation so we have to create it be able to read attachment's data
                    database.TransactionalStorage.Batch(accessor =>
                    {
                        var streamReader = new StreamReader(attachment.Data());
                        // we have to read it into memory because we after exiting the batch an attachment's data stream will be closed
                        fieldWithCaching.SetValue(streamReader.ReadToEnd());
                    });
                }

                yield return(fieldWithCaching);

                yield break;
            }
            if (Equals(value, string.Empty))
            {
                yield return(CreateFieldWithCaching(name, Constants.EmptyString, storage,
                                                    Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO));

                yield break;
            }
            var dynamicNullObject = value as DynamicNullObject;

            if (ReferenceEquals(dynamicNullObject, null) == false)
            {
                if (dynamicNullObject.IsExplicitNull)
                {
                    var sortOptions = indexDefinition.GetSortOption(name, query: null);
                    if (sortOptions == null ||
                        sortOptions.Value == SortOptions.String ||
                        sortOptions.Value == SortOptions.None ||
                        sortOptions.Value == SortOptions.StringVal ||
                        sortOptions.Value == SortOptions.Custom)
                    {
                        yield return(CreateFieldWithCaching(name, Constants.NullValue, storage,
                                                            Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO));
                    }

                    foreach (var field in CreateNumericFieldWithCaching(name, GetNullValueForSorting(sortOptions), storage, termVector))
                    {
                        yield return(field);
                    }
                }
                yield break;
            }
            var boostedValue = value as BoostedValue;

            if (boostedValue != null)
            {
                foreach (var field in CreateFields(name, boostedValue.Value, storage, false, termVector))
                {
                    field.Boost     = boostedValue.Boost;
                    field.OmitNorms = false;
                    yield return(field);
                }
                yield break;
            }


            var abstractField = value as AbstractField;

            if (abstractField != null)
            {
                yield return(abstractField);

                yield break;
            }
            var bytes = value as byte[];

            if (bytes != null)
            {
                yield return(CreateBinaryFieldWithCaching(name, bytes, storage, fieldIndexingOptions, termVector));

                yield break;
            }

            var itemsToIndex = value as IEnumerable;

            if (itemsToIndex != null && ShouldTreatAsEnumerable(itemsToIndex))
            {
                int count = 1;

                if (nestedArray == false)
                {
                    yield return(new Field(name + "_IsArray", "true", storage, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO));
                }

                foreach (var itemToIndex in itemsToIndex)
                {
                    if (!CanCreateFieldsForNestedArray(itemToIndex, fieldIndexingOptions))
                    {
                        continue;
                    }

                    multipleItemsSameFieldCount.Add(count++);
                    foreach (var field in CreateFields(name, itemToIndex, storage, nestedArray: true, defaultTermVector: defaultTermVector, analyzed: analyzed))
                    {
                        yield return(field);
                    }

                    multipleItemsSameFieldCount.RemoveAt(multipleItemsSameFieldCount.Count - 1);
                }

                yield break;
            }

            if (Equals(fieldIndexingOptions, Field.Index.NOT_ANALYZED) ||
                Equals(fieldIndexingOptions, Field.Index.NOT_ANALYZED_NO_NORMS))// explicitly not analyzed
            {
                // date time, time span and date time offset have the same structure fo analyzed and not analyzed.
                if (!(value is DateTime) && !(value is DateTimeOffset) && !(value is TimeSpan))
                {
                    yield return(CreateFieldWithCaching(name, value.ToString(), storage,
                                                        indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));

                    yield break;
                }
            }
            if (value is string)
            {
                var index = indexDefinition.GetIndex(name, Field.Index.ANALYZED);
                yield return(CreateFieldWithCaching(name, value.ToString(), storage, index, termVector));

                yield break;
            }

            if (value is TimeSpan)
            {
                var val = (TimeSpan)value;
                yield return(CreateFieldWithCaching(name, val.ToString("c", CultureInfo.InvariantCulture), storage,
                                                    indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
            }
            else if (value is DateTime)
            {
                var val          = (DateTime)value;
                var dateAsString = val.GetDefaultRavenFormat();
                if (val.Kind == DateTimeKind.Utc)
                {
                    dateAsString += "Z";
                }
                yield return(CreateFieldWithCaching(name, dateAsString, storage,
                                                    indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
            }
            else if (value is DateTimeOffset)
            {
                var val = (DateTimeOffset)value;

                string dtoStr;
                if (Equals(fieldIndexingOptions, Field.Index.NOT_ANALYZED) || Equals(fieldIndexingOptions, Field.Index.NOT_ANALYZED_NO_NORMS))
                {
                    dtoStr = val.ToString(Default.DateTimeOffsetFormatsToWrite, CultureInfo.InvariantCulture);
                }
                else
                {
                    dtoStr = val.UtcDateTime.GetDefaultRavenFormat(true);
                }
                yield return(CreateFieldWithCaching(name, dtoStr, storage,
                                                    indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
            }
            else if (value is bool)
            {
                yield return(new Field(name, ((bool)value) ? "true" : "false", storage,
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
            }
            else if (value is double)
            {
                var d = (double)value;
                yield return(CreateFieldWithCaching(name, d.ToString("r", CultureInfo.InvariantCulture), storage,
                                                    indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
            }
            else if (value is decimal)
            {
                var d = (decimal)value;
                var s = d.ToString(CultureInfo.InvariantCulture);
                if (s.Contains('.'))
                {
                    s = s.TrimEnd('0');
                    if (s.EndsWith("."))
                    {
                        s = s.Substring(0, s.Length - 1);
                    }
                }
                yield return(CreateFieldWithCaching(name, s, storage,
                                                    indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
            }
            else if (value is Enum)
            {
                yield return(CreateFieldWithCaching(name, value.ToString(), storage,
                                                    indexDefinition.GetIndex(name, Field.Index.ANALYZED_NO_NORMS), termVector));
            }
            else if (value is IConvertible) // we need this to store numbers in invariant format, so JSON could read them
            {
                var convert = ((IConvertible)value);
                yield return(CreateFieldWithCaching(name, convert.ToString(CultureInfo.InvariantCulture), storage,
                                                    indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
            }
            else if (value is IDynamicJsonObject)
            {
                var inner = ((IDynamicJsonObject)value).Inner;
                yield return(CreateFieldWithCaching(name + "_ConvertToJson", "true", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO));

                yield return(CreateFieldWithCaching(name, inner.ToString(Formatting.None), storage,
                                                    indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
            }
            else
            {
                var jsonVal = RavenJToken.FromObject(value).ToString(Formatting.None);
                if (jsonVal.StartsWith("{") || jsonVal.StartsWith("["))
                {
                    yield return(CreateFieldWithCaching(name + "_ConvertToJson", "true", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO));
                }
                else if (jsonVal.StartsWith("\"") && jsonVal.EndsWith("\"") && jsonVal.Length > 1)
                {
                    jsonVal = jsonVal.Substring(1, jsonVal.Length - 2);
                }
                yield return(CreateFieldWithCaching(name, jsonVal, storage,
                                                    indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
            }


            foreach (var numericField in CreateNumericFieldWithCaching(name, value, storage, termVector))
            {
                yield return(numericField);
            }
        }
			public FieldCacheKey(string name, Field.Index? index, Field.Store store, int[] multipleItemsSameField)
			{
				this.name = name;
				this.index = index;
				this.store = store;
				this.multipleItemsSameField = multipleItemsSameField;
			}