コード例 #1
0
        private static AbstractField CreateField(IndexFieldInfo fieldInfo)
        {
            NumericField nf;

            switch (fieldInfo.Type)
            {
            case FieldInfoType.StringField:
                return(new Field(fieldInfo.Name, fieldInfo.Value, fieldInfo.Store, fieldInfo.Index, fieldInfo.TermVector));

            case FieldInfoType.IntField:
                nf = new NumericField(fieldInfo.Name, fieldInfo.Store, fieldInfo.Index != Field.Index.NO);
                nf.SetIntValue(Int32.Parse(fieldInfo.Value, CultureInfo.InvariantCulture));
                return(nf);

            case FieldInfoType.LongField:
                nf = new NumericField(fieldInfo.Name, 8, fieldInfo.Store, fieldInfo.Index != Field.Index.NO);
                nf.SetLongValue(Int64.Parse(fieldInfo.Value, CultureInfo.InvariantCulture));
                return(nf);

            case FieldInfoType.SingleField:
                nf = new NumericField(fieldInfo.Name, fieldInfo.Store, fieldInfo.Index != Field.Index.NO);
                nf.SetFloatValue(Single.Parse(fieldInfo.Value, CultureInfo.InvariantCulture));
                return(nf);

            case FieldInfoType.DoubleField:
                nf = new NumericField(fieldInfo.Name, 8, fieldInfo.Store, fieldInfo.Index != Field.Index.NO);
                nf.SetDoubleValue(Double.Parse(fieldInfo.Value, CultureInfo.InvariantCulture));
                return(nf);

            default:
                throw new NotImplementedException("IndexFieldInfo." + fieldInfo.Type);
            }
        }
コード例 #2
0
        internal static NumericField SetValue(this NumericField field, ValueType value)
        {
            if (value.GetType().IsEnum)
            {
                value = (ValueType)Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType()));
            }

            if (value is int)
            {
                return(field.SetIntValue((int)value));
            }
            if (value is long)
            {
                return(field.SetLongValue((long)value));
            }
            if (value is double)
            {
                return(field.SetDoubleValue((double)value));
            }
            if (value is float)
            {
                return(field.SetFloatValue((float)value));
            }

            throw new ArgumentException("Unable to store ValueType " + value.GetType() + " as NumericField.", "value");
        }
コード例 #3
0
        private Document AnalyzerDocument(RecordInfo record)
        {
            Document doc = new Document();

            doc.Add(new Field("ModuleType", record.ModuleType, Field.Store.YES, Field.Index.NOT_ANALYZED));
            doc.Add(new Field("TableName", record.TableName, Field.Store.YES, Field.Index.NOT_ANALYZED));
            doc.Add(new Field("RowId", record.RowId, Field.Store.YES, Field.Index.NOT_ANALYZED));
            doc.Add(new Field("CollectTime", record.CollectTime.ToString("yyyy-MM-dd HH:mm:ss"), Field.Store.YES, Field.Index.NOT_ANALYZED));
            doc.Add(new Field("Title", record.Title, Field.Store.YES, Field.Index.ANALYZED));
            doc.Add(new Field("Body", record.Body, Field.Store.YES, Field.Index.ANALYZED));

            if (record.StringTags != null && record.StringTags.Any())
            {
                foreach (var tag in record.StringTags)
                {
                    doc.Add(new Field(tag.Name, tag.Value, tag.Store, tag.Index));
                }
            }

            if (record.FloatTags != null && record.FloatTags.Any())
            {
                foreach (var tag in record.FloatTags)
                {
                    NumericField field = new NumericField(tag.Name, tag.Store, tag.Index != Field.Index.NO);
                    field = field.SetFloatValue(tag.Value);
                    doc.Add(field);
                }
            }

            return(doc);
        }
コード例 #4
0
        /// <summary>
        /// Recursively tokenize the object into fields whose names are available via dot notation.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="prefix"></param>
        /// <param name="dictionary"></param>
        private static void TokenizeObject(JObject obj, string prefix, ref Dictionary <string, AbstractField> dictionary)
        {
            if (obj == null)
            {
                return;
            }

            //TODO: Add property-based ("$propertyName") conventions that allow the parameters to be customized.
            foreach (var property in obj.Properties().Where(p => p.Value != null))
            {
                var fieldName = String.IsNullOrEmpty(prefix) ? property.Name : prefix + "." + property.Name;
                switch (property.Value.Type)
                {
                case JTokenType.Date:
                    var dateString = DateTools.DateToString((DateTime)property.Value, DateTools.Resolution.MILLISECOND);
                    var dateField  = new Field(fieldName, dateString, Field.Store.YES, Field.Index.NOT_ANALYZED, Field.TermVector.YES);

                    dictionary.Add(fieldName, dateField);
                    break;

                case JTokenType.TimeSpan:
                    var timeSpanField = new NumericField(fieldName, Field.Store.YES, true);
                    timeSpanField.SetLongValue(((TimeSpan)property.Value).Ticks);
                    dictionary.Add(fieldName, timeSpanField);
                    break;

                case JTokenType.Integer:
                    var intField = new NumericField(fieldName, Field.Store.YES, true);
                    intField.SetIntValue((int)property.Value);
                    dictionary.Add(fieldName, intField);
                    break;

                case JTokenType.Float:
                    var floatField = new NumericField(fieldName, Field.Store.YES, true);
                    floatField.SetFloatValue((float)property.Value);
                    dictionary.Add(fieldName, floatField);
                    break;

                case JTokenType.Guid:
                    var guidField = new Field(fieldName, property.Value.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED,
                                              Field.TermVector.NO);
                    dictionary.Add(fieldName, guidField);
                    break;

                case JTokenType.Object:
                    TokenizeObject(property.Value as JObject, fieldName, ref dictionary);
                    break;

                default:
                    if (String.IsNullOrEmpty(property.Value.ToString()) == false)
                    {
                        var stringField = new Field(fieldName, property.Value.ToString(), Field.Store.YES, Field.Index.ANALYZED,
                                                    Field.TermVector.WITH_POSITIONS_OFFSETS);
                        dictionary.Add(fieldName, stringField);
                    }
                    break;
                }
            }
        }
コード例 #5
0
ファイル: Index.cs プロジェクト: jmajeti/barista-sharepoint
        protected static Document CloneDocument(Document luceneDoc)
        {
            var clonedDocument = new Document();

            foreach (AbstractField field in luceneDoc.GetFields())
            {
                var numericField = field as NumericField;
                if (numericField != null)
                {
                    var clonedNumericField = new NumericField(numericField.Name,
                                                              numericField.IsStored ? Field.Store.YES : Field.Store.NO,
                                                              numericField.IsIndexed);
                    var numericValue = numericField.NumericValue;
                    if (numericValue is int)
                    {
                        clonedNumericField.SetIntValue((int)numericValue);
                    }
                    else if (numericValue is long)
                    {
                        clonedNumericField.SetLongValue((long)numericValue);
                    }
                    else if (numericValue is double)
                    {
                        clonedNumericField.SetDoubleValue((double)numericValue);
                    }
                    else if (numericValue is float)
                    {
                        clonedNumericField.SetFloatValue((float)numericValue);
                    }
                    clonedDocument.Add(clonedNumericField);
                }
                else
                {
                    Field clonedField;
                    if (field.IsBinary)
                    {
                        clonedField = new Field(field.Name, field.GetBinaryValue(),
                                                field.IsStored ? Field.Store.YES : Field.Store.NO);
                    }
                    else if (field.StringValue != null)
                    {
                        clonedField = new Field(field.Name, field.StringValue,
                                                field.IsStored ? Field.Store.YES : Field.Store.NO,
                                                field.IsIndexed ? Field.Index.ANALYZED_NO_NORMS : Field.Index.NOT_ANALYZED_NO_NORMS,
                                                field.IsTermVectorStored ? Field.TermVector.YES : Field.TermVector.NO);
                    }
                    else
                    {
                        //probably token stream, and we can't handle fields with token streams, so we skip this.
                        continue;
                    }
                    clonedDocument.Add(clonedField);
                }
            }
            return(clonedDocument);
        }
コード例 #6
0
        private static Document CloneDocument(Document luceneDoc)
        {
            var clonedDocument = new Document();

            foreach (AbstractField field in luceneDoc.GetFields())
            {
                var numericField = field as NumericField;
                if (numericField != null)
                {
                    var clonedNumericField = new NumericField(numericField.Name(),
                                                              numericField.IsStored() ? Field.Store.YES : Field.Store.NO,
                                                              numericField.IsIndexed());
                    var numericValue = numericField.GetNumericValue();
                    if (numericValue is int)
                    {
                        clonedNumericField.SetIntValue((int)numericValue);
                    }
                    else if (numericValue is long)
                    {
                        clonedNumericField.SetLongValue((long)numericValue);
                    }
                    else if (numericValue is double)
                    {
                        clonedNumericField.SetDoubleValue((double)numericValue);
                    }
                    else if (numericValue is float)
                    {
                        clonedNumericField.SetFloatValue((float)numericValue);
                    }
                    clonedDocument.Add(clonedNumericField);
                }
                else
                {
                    Field clonedField;
                    if (field.IsBinary())
                    {
                        clonedField = new Field(field.Name(), field.BinaryValue(),
                                                field.IsStored() ? Field.Store.YES : Field.Store.NO);
                    }
                    else
                    {
                        clonedField = new Field(field.Name(), field.StringValue(),
                                                field.IsStored() ? Field.Store.YES : Field.Store.NO,
                                                field.IsIndexed() ? Field.Index.ANALYZED_NO_NORMS : Field.Index.NOT_ANALYZED_NO_NORMS);
                    }
                    clonedDocument.Add(clonedField);
                }
            }
            return(clonedDocument);
        }
コード例 #7
0
ファイル: LuceneBulid.cs プロジェクト: hfendou/WebMVCSite
        /// <summary>
        /// 将T转换成doc
        /// </summary>
        /// <param name="model"></param>
        /// <param name="fieldModelList"></param>
        /// <returns></returns>
        private Document ParseModeltoDoc(T model, IEnumerable <FieldDataModel> fieldModelList)
        {
            Document document = new Document();
            Type     type     = model.GetType();

            foreach (var item in fieldModelList)
            {
                PropertyInfo propertyInfo  = type.GetProperty(item.PropertyName);
                var          propertyValue = propertyInfo.GetValue(model);
                if (propertyValue != null)
                {
                    string     valueString = propertyValue.ToString();
                    IFieldable fieldable   = null;
                    if (item.FieldType == TypeCode.String)
                    {
                        fieldable = new Field(item.FieldName, valueString, item.Store, item.Index, item.TermVector);
                    }
                    else
                    {
                        NumericField numericField = new NumericField(item.FieldName, item.Store, item.Index == Field.Index.ANALYZED_NO_NORMS);
                        switch (item.FieldType)
                        {
                        case TypeCode.Double:
                            numericField.SetDoubleValue(Convert.ToDouble(valueString));
                            break;

                        case TypeCode.Single:
                            numericField.SetFloatValue(Convert.ToSingle(valueString));
                            break;

                        case TypeCode.Int32:
                            numericField.SetIntValue(Convert.ToInt32(valueString));
                            break;

                        case TypeCode.Int64:
                            numericField.SetLongValue(Convert.ToInt64(valueString));
                            break;

                        default:
                            break;
                        }
                        fieldable = numericField;
                    }
                    document.Add(fieldable);
                }
            }
            return(document);
        }
コード例 #8
0
        /// <summary>
        /// Converts the list item to document.
        /// </summary>
        /// <param name="listItem">The list item.</param>
        /// <returns>Document.</returns>
        public static Document ConvertListItemToDocument(SPListItem listItem)
        {
            var tokenDictionary = new Dictionary <string, AbstractField>();

            foreach (var field in listItem.Fields.OfType <SPField>().Where(f => f.Hidden == false))
            {
                switch (field.Type)
                {
                case SPFieldType.DateTime:
                    var dateString = DateTools.DateToString((DateTime)listItem[field.Id], DateTools.Resolution.MILLISECOND);
                    var dateField  = new Field(field.Title, dateString, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES);

                    tokenDictionary.Add(field.Title, dateField);
                    break;

                case SPFieldType.Integer:
                    var intField = new NumericField(field.Title, Field.Store.YES, true);
                    intField.SetIntValue((int)listItem[field.Id]);
                    tokenDictionary.Add(field.Title, intField);
                    break;

                case SPFieldType.Number:
                    var numberField = new NumericField(field.Title, Field.Store.YES, true);
                    numberField.SetFloatValue(Convert.ToSingle(listItem[field.Id]));
                    tokenDictionary.Add(field.Title, numberField);
                    break;

                default:
                    var textValue   = field.GetFieldValueAsText(listItem[field.Id]);
                    var stringField = new Field(field.Title, textValue, Field.Store.YES, Field.Index.ANALYZED,
                                                Field.TermVector.WITH_POSITIONS_OFFSETS);
                    tokenDictionary.Add(field.Title, stringField);
                    break;
                }
            }

            var doc = new Document();

            //Add individual fields.
            foreach (var kvp in tokenDictionary)
            {
                doc.Add(kvp.Value);
            }

            return(doc);
        }
コード例 #9
0
        public IFieldable CreateLuceneField(string fieldName, object fieldValue)
        {
            if (!Numeric)
            {
                return(new Field(fieldName, LuceneUtility.ToFieldStringValue(fieldValue), Store, Index)
                {
                    Boost = Boost
                });
            }

            var field = new NumericField(fieldName, Store, Index != Field.Index.NO)
            {
                Boost = Boost
            };

            if (fieldValue is Int32)
            {
                field.SetIntValue((int)fieldValue);
            }
            else if (fieldValue is Int64)
            {
                field.SetLongValue((long)fieldValue);
            }
            else if (fieldValue is Single)
            {
                field.SetFloatValue((float)fieldValue);
            }
            else if (fieldValue is Double)
            {
                field.SetDoubleValue((double)fieldValue);
            }
            else if (fieldValue is Decimal)
            {
                field.SetDoubleValue((double)(decimal)fieldValue);
            }
            else
            {
                throw new NotSupportedException();
            }

            return(field);
        }
コード例 #10
0
        internal static NumericField SetValue(this NumericField field, ValueType value)
        {
            if (value is int)
            {
                return(field.SetIntValue((int)value));
            }
            if (value is long)
            {
                return(field.SetLongValue((long)value));
            }
            if (value is double)
            {
                return(field.SetDoubleValue((double)value));
            }
            if (value is float)
            {
                return(field.SetFloatValue((float)value));
            }

            throw new ArgumentException("Unable to store ValueType " + value.GetType() + " as NumericField.", "value");
        }
コード例 #11
0
        /// <summary>
        /// 将对象转成Lucene里面的Document类型
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="columnFields"></param>
        /// <returns></returns>
        public static Document Convert(object obj, ColumnField[] columnFields)
        {
            Document document = null;

            if (obj != null)
            {
                document = new Document();
                Type type = obj.GetType();
                foreach (ColumnField columnField in columnFields)
                {
                    if (columnField.IsCustomScore)
                    {//为文档增加自定义评分列
                        NumericField numericField = new NumericField(columnField.Column, columnField.Store, true);
                        numericField.SetIntValue(1);
                        document.Add(numericField);
                        columnField.Type = FieldType.INT32;
                        continue;
                    }
                    Lucene.Net.Documents.Field.Store store = columnField.Store;

                    string       fieldName    = columnField.Column;
                    PropertyInfo propertyInfo = type.GetProperty(fieldName);
                    if (propertyInfo != null)
                    {
                        object value = propertyInfo.GetValue(obj, null);
                        if (value != null)
                        {
                            if (columnField.Index == Field.Index.ANALYZED ||//分词建索引
                                columnField.Index == Field.Index.ANALYZED_NO_NORMS)   //分词建索引,不支持权重
                            {
                                Field field = new Field(fieldName, value.ToString(), store, columnField.Index);
                                field.Boost = columnField.Boost;
                                document.Add(field);
                                columnField.Type = FieldType.STRING;
                            }
                            else
                            {
                                string typeName = value.GetType().Name;
                                if (typeName == FieldType.SINGLE)
                                {
                                    NumericField numericField = new NumericField(fieldName, store, true);
                                    numericField.SetFloatValue(System.Convert.ToSingle(value));
                                    numericField.Boost = columnField.Boost;
                                    document.Add(numericField);
                                    columnField.Type = FieldType.SINGLE;
                                }
                                else if (typeName == FieldType.DOUBLE || typeName == FieldType.DECIMAL)
                                {
                                    NumericField numericField = new NumericField(fieldName, store, true);
                                    numericField.SetDoubleValue(System.Convert.ToDouble(value));
                                    numericField.Boost = columnField.Boost;
                                    document.Add(numericField);
                                    columnField.Type = FieldType.DOUBLE;
                                }
                                else if (typeName == FieldType.INT32)
                                {
                                    NumericField numericField = new NumericField(fieldName, store, true);
                                    numericField.SetIntValue(System.Convert.ToInt32(value));
                                    numericField.Boost = columnField.Boost;
                                    document.Add(numericField);
                                    columnField.Type = FieldType.INT32;
                                }
                                else if (typeName == FieldType.INT64)
                                {
                                    NumericField numericField = new NumericField(fieldName, store, true);
                                    numericField.SetLongValue(System.Convert.ToInt64(value));
                                    numericField.Boost = columnField.Boost;
                                    document.Add(numericField);
                                    columnField.Type = FieldType.INT64;
                                }
                                else if (typeName == FieldType.DATETIME)
                                {
                                    NumericField numericField = new NumericField(fieldName, store, true);
                                    DateTime     dateTime     = System.Convert.ToDateTime(value);
                                    numericField.SetLongValue(dateTime.Ticks);
                                    numericField.Boost = columnField.Boost;
                                    document.Add(numericField);
                                    columnField.Type = FieldType.DATETIME;
                                }
                                else
                                {
                                    Field field = new Field(fieldName, value.ToString(), store, columnField.Index);
                                    field.Boost = columnField.Boost;
                                    document.Add(field);
                                    columnField.Type = FieldType.STRING;
                                }
                            }
                        }
                    }
                }
            }
            return(document);
        }
コード例 #12
0
        private static void CreateIndexContent()
        {
            using (FSDirectory directory = FSDirectory.Open(new DirectoryInfo(m_directoryPath), new NativeFSLockFactory())) //指定索引文件(打开索引目录) FS指的是就是FileSystem
            {
                bool isUpdate = IndexReader.IndexExists(directory);                                                         //IndexReader:对索引进行读取的类。该语句的作用:判断索引库文件夹是否存在以及索引特征文件是否存在。
                if (isUpdate)
                {
                    //同时只能有一段代码对索引库进行写操作。当使用IndexWriter打开directory时会自动对索引库文件上锁。
                    //如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁(提示一下:如果我现在正在写着已经加锁了,但是还没有写完,这时候又来一个请求,那么不就解锁了吗?这个问题后面会解决)
                    if (IndexWriter.IsLocked(directory))
                    {
                        IndexWriter.Unlock(directory);
                    }
                }

                using (IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, IndexWriter.MaxFieldLength.UNLIMITED))                //向索引库中写索引。这时在这里加锁。
                {
                    //如果队列中有数据,获取队列中的数据写到Lucene.Net中。
                    while (Queue.Count > 0)
                    {
                        KeyValuePair <T, LuceneTypeEnum> keyValuePair = Queue.Dequeue();
                        T            model         = keyValuePair.Key;
                        Type         type          = model.GetType();
                        PropertyInfo propertyInfo  = type.GetProperty(m_luceneDataModels[0].PropertyName);
                        var          propertyValue = propertyInfo.GetValue(model);
                        string       valueString   = propertyValue != null?propertyValue.ToString() : null;

                        writer.DeleteDocuments(new Term(m_luceneDataModels[0].FieldName, valueString));                        //删除
                        if (keyValuePair.Value == LuceneTypeEnum.Delete)
                        {
                            continue;
                        }
                        //表示一篇文档。
                        Document document = new Document();
                        //Field.Store.YES:表示是否存储原值。只有当Field.Store.YES在后面才能用doc.Get("number")取出值来.Field.Index. NOT_ANALYZED:不进行分词保存
                        //Field.Index. ANALYZED:进行分词保存:也就是要进行全文的字段要设置分词 保存(因为要进行模糊查询
                        //Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS:不仅保存分词还保存分词的距离。
                        foreach (FieldDataModel item in m_luceneDataModels)
                        {
                            propertyInfo  = type.GetProperty(item.PropertyName);
                            propertyValue = propertyInfo.GetValue(model);
                            if (propertyValue != null)
                            {
                                valueString = propertyValue.ToString();
                                IFieldable fieldable = null;
                                if (item.FieldType == TypeCode.String)
                                {
                                    fieldable = new Field(item.FieldName, valueString, item.Store, item.Index, item.TermVector);
                                }
                                else
                                {
                                    NumericField numericField = new NumericField(item.FieldName, item.Store, item.Index == Field.Index.ANALYZED_NO_NORMS);
                                    switch (item.FieldType)
                                    {
                                    case TypeCode.Double:
                                        numericField.SetDoubleValue(Convert.ToDouble(valueString));
                                        break;

                                    case TypeCode.Single:
                                        numericField.SetFloatValue(Convert.ToSingle(valueString));
                                        break;

                                    case TypeCode.Int32:
                                        numericField.SetIntValue(Convert.ToInt32(valueString));
                                        break;

                                    case TypeCode.Int64:
                                        numericField.SetLongValue(Convert.ToInt64(valueString));
                                        break;

                                    default:
                                        break;
                                    }
                                    fieldable = numericField;
                                }
                                document.Add(fieldable);
                            }
                        }
                        writer.AddDocument(document);
                    }
                }                //会自动解锁。
            }
        }
コード例 #13
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>
        private static IEnumerable <AbstractField> CreateFields(string name, object value, IndexDefinition indexDefinition, Field.Store defaultStorage)
        {
            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 (value == null)
            {
                yield return(new Field(name, "NULL_VALUE", indexDefinition.GetStorage(name, defaultStorage),
                                       Field.Index.NOT_ANALYZED));

                yield break;
            }
            if (value is DynamicNullObject)
            {
                if (((DynamicNullObject)value).IsExplicitNull)
                {
                    yield return(new Field(name, "NULL_VALUE", indexDefinition.GetStorage(name, defaultStorage),
                                           Field.Index.NOT_ANALYZED));
                }
                yield break;
            }

            if (value is AbstractField)
            {
                yield return((AbstractField)value);

                yield break;
            }


            var itemsToIndex = value as IEnumerable;

            if (itemsToIndex != null && ShouldTreatAsEnumerable(itemsToIndex))
            {
                yield return(new Field(name + "_IsArray", "true", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));

                foreach (var itemToIndex in itemsToIndex)
                {
                    foreach (var field in CreateFields(name, itemToIndex, indexDefinition, defaultStorage))
                    {
                        yield return(field);
                    }
                }
                yield break;
            }

            if (indexDefinition.GetIndex(name, null) == Field.Index.NOT_ANALYZED)// explicitly not analyzed
            {
                yield return(new Field(name, value.ToString(), indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED)));

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

                yield break;
            }

            if (value is DateTime)
            {
                yield return(new Field(name, DateTools.DateToString((DateTime)value, DateTools.Resolution.MILLISECOND),
                                       indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED)));
            }
            else if (value is bool)
            {
                yield return(new Field(name, ((bool)value) ? "true" : "false", indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED)));
            }
            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(new Field(name, convert.ToString(CultureInfo.InvariantCulture), indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED)));
            }
            else if (value is DynamicJsonObject)
            {
                var inner = ((DynamicJsonObject)value).Inner;
                yield return(new Field(name + "_ConvertToJson", "true", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));

                yield return(new Field(name, inner.ToString(), indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED)));
            }
            else
            {
                yield return(new Field(name + "_ConvertToJson", "true", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));

                yield return(new Field(name, JToken.FromObject(value).ToString(), indexDefinition.GetStorage(name, defaultStorage),
                                       indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED)));
            }


            var numericField = new NumericField(name + "_Range", indexDefinition.GetStorage(name, defaultStorage), true);

            if (value is int)
            {
                if (indexDefinition.GetSortOption(name) == SortOptions.Long)
                {
                    yield return(numericField.SetLongValue((int)value));
                }
                else
                {
                    yield return(numericField.SetIntValue((int)value));
                }
            }
            if (value is long)
            {
                yield return(numericField
                             .SetLongValue((long)value));
            }
            if (value is decimal)
            {
                yield return(numericField
                             .SetDoubleValue((double)(decimal)value));
            }
            if (value is float)
            {
                if (indexDefinition.GetSortOption(name) == SortOptions.Double)
                {
                    yield return(numericField.SetDoubleValue((float)value));
                }
                else
                {
                    yield return(numericField.SetFloatValue((float)value));
                }
            }
            if (value is double)
            {
                yield return(numericField
                             .SetDoubleValue((double)value));
            }
        }
        /// <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>
        private IEnumerable <AbstractField> CreateFields(string name, JToken value, Field.Store defaultStorage, Field.TermVector defaultTermVector)
        {
            if (name.IsNullOrWhiteSpace())
            {
                throw new ArgumentException(@"Field must be not null, not empty and cannot contain whitespace", "name");
            }

            var fieldIndexingOptions = m_indexDefinition.GetIndex(name, null);
            var storage    = m_indexDefinition.GetStorage(name, defaultStorage);
            var termVector = m_indexDefinition.GetTermVector(name, defaultTermVector);

            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 for analyzed and not analyzed.
                if (value.Type != JTokenType.Date && value.Type != JTokenType.TimeSpan)
                {
                    yield return(new Field(name, value.ToString(), storage,
                                           m_indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
                }
            }
            else
            {
                switch (value.Type)
                {
                case JTokenType.Array:
                {
                    //Add each item in the array as a field with the same name.

                    //Return an _IsArray field.
                    if (Equals(storage, Field.Store.NO) == false)
                    {
                        yield return(new Field(name + "_IsArray", "true", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO));
                    }

                    var jArray = value as JArray;
                    if (jArray == null)
                    {
                        throw new InvalidOperationException("Shouldn't Happen");
                    }

                    foreach (var arrayValue in jArray)
                    {
                        if (CanCreateFieldsForNestedArray(arrayValue, fieldIndexingOptions) == false)
                        {
                            continue;
                        }

                        foreach (var field in CreateFields(name, arrayValue, storage, Field.TermVector.NO))
                        {
                            yield return(field);
                        }
                    }
                    break;
                }

                case JTokenType.Boolean:
                {
                    yield return(new Field(name, (value.Value <bool>()) ? "true" : "false", storage,
                                           m_indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
                }
                break;

                case JTokenType.Bytes:
                {
                    var bytes = value.Value <byte[]>();
                    if (bytes != null)
                    {
                        yield return(CreateBinaryField(name, bytes, storage, fieldIndexingOptions, termVector));
                    }
                }
                break;

                case JTokenType.Date:
                {
                    var val          = value.Value <DateTime>();
                    var dateAsString = val.ToString(Default.DateTimeFormatsToWrite);
                    if (val.Kind == DateTimeKind.Utc)
                    {
                        dateAsString += "Z";
                    }
                    yield return(new Field(name, dateAsString, storage,
                                           m_indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS),
                                           termVector));
                }
                break;

                case JTokenType.Guid:
                {
                    yield return(new Field(name, value.Value <Guid>().ToString(), storage,
                                           m_indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
                }
                break;

                case JTokenType.None:
                case JTokenType.Null:
                {
                    yield return(new Field(name, Constants.NullValue, storage,
                                           Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO));
                }
                break;

                case JTokenType.Object:
                {
                    //Add an _IsObject field
                    if (Equals(storage, Field.Store.NO) == false)
                    {
                        yield return(new Field(name + "_IsObject", "true", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO));
                    }

                    //Recursively add properties on the object.
                    foreach (var objectValue in value.Children <JProperty>())
                    {
                        if (CanCreateFieldsForNestedObject(objectValue, fieldIndexingOptions) == false)
                        {
                            continue;
                        }

                        foreach (var field in CreateFields(name + "." + objectValue.Name, objectValue.Value, storage, defaultTermVector))
                        {
                            yield return(field);
                        }
                    }
                }
                break;

                case JTokenType.String:
                {
                    if (Equals(value.Value <string>(), string.Empty))
                    {
                        yield return(new Field(name, Constants.EmptyString, storage,
                                               Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO));

                        yield break;
                    }
                    var index = m_indexDefinition.GetIndex(name, Field.Index.ANALYZED);
                    yield return(new Field(name, value.ToString(), storage, index, termVector));
                }
                break;

                case JTokenType.Float:
                {
                    var f     = value.Value <float>();
                    var index = m_indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS);
                    yield return(new Field(name, f.ToString(CultureInfo.InvariantCulture), storage, index, termVector));

                    var numericField = new NumericField(name + "_Range", storage, true);
                    if (m_indexDefinition.GetSortOption(name) == SortOptions.Double)
                    {
                        yield return(numericField.SetDoubleValue(value.Value <double>()));
                    }
                    else
                    {
                        yield return(numericField.SetFloatValue(value.Value <float>()));
                    }
                }
                break;

                case JTokenType.Integer:
                {
                    var i     = value.Value <int>();
                    var index = m_indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS);
                    yield return(new Field(name, i.ToString(CultureInfo.InvariantCulture), storage, index, termVector));

                    var numericField = new NumericField(name + "_Range", storage, true);
                    if (m_indexDefinition.GetSortOption(name) == SortOptions.Long)
                    {
                        yield return(numericField.SetLongValue(value.Value <long>()));
                    }
                    else
                    {
                        yield return(numericField.SetIntValue(value.Value <int>()));
                    }
                }
                break;

                case JTokenType.TimeSpan:
                {
                    var val   = value.Value <TimeSpan>();
                    var index = m_indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS);
                    yield return(new Field(name, val.ToString("c"), storage, index, termVector));

                    var numericField = new NumericField(name + "_Range", storage, true);
                    yield return(numericField.SetLongValue(val.Ticks));
                }
                break;

                case JTokenType.Uri:
                {
                    yield return(new Field(name, value.Value <Uri>().ToString(), storage,
                                           m_indexDefinition.GetIndex(name, Field.Index.NOT_ANALYZED_NO_NORMS), termVector));
                }
                break;

                case JTokenType.Undefined:
                case JTokenType.Raw:
                case JTokenType.Property:
                case JTokenType.Constructor:
                case JTokenType.Comment:
                    //Do Nothing...
                    break;

                default:
                    throw new ArgumentOutOfRangeException("The specified JToken Type: " + value.Type + " is invalid or has not been implemented.");
                }
            }
        }