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); } }
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"); }
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); }
/// <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; } } }
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); }
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); }
/// <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); }
/// <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); }
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); }
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"); }
/// <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); }
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); } } //会自动解锁。 } }
/// <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."); } } }