protected override int GetFields <T>(T instance, LazyStringValue key, object document, JsonOperationContext indexContext, IWriteOperationBuffer writeBuffer) { if (!(document is ObjectInstance documentToProcess)) { return(0); } int newFields = 0; if (key != null) { instance.Add(GetOrCreateKeyField(key)); newFields++; } if (_reduceOutput) { var reduceResult = JsBlittableBridge.Translate(indexContext, documentToProcess.Engine, documentToProcess); instance.Add(GetReduceResultValueField(reduceResult, writeBuffer)); newFields++; } foreach (var(property, propertyDescriptor) in documentToProcess.GetOwnProperties()) { if (_fields.TryGetValue(property, out var field) == false) { field = _fields[property] = IndexField.Create(property, new IndexFieldOptions(), _allFields); } object value; var actualValue = propertyDescriptor.Value; if (actualValue.IsObject() && actualValue.IsArray() == false) { //In case TryDetectDynamicFieldCreation finds a dynamic field it will populate 'field.Name' with the actual property name //so we must use field.Name and not property from this point on. var val = TryDetectDynamicFieldCreation(property, actualValue.AsObject(), field); if (val != null) { if (val.IsObject() && val.AsObject().TryGetValue("$spatial", out _)) { actualValue = val; //Here we populate the dynamic spatial field that will be handled below. } else { value = TypeConverter.ToBlittableSupportedType(val, flattenArrays: false, forIndexing: true, engine: documentToProcess.Engine, context: indexContext); newFields += GetRegularFields(instance, field, value, indexContext, out _); continue; } } var objectValue = actualValue.AsObject(); if (objectValue.HasOwnProperty("$spatial") && objectValue.TryGetValue("$spatial", out var inner)) { SpatialField spatialField; IEnumerable <AbstractField> spatial; if (inner.IsString()) { spatialField = StaticIndexBase.GetOrCreateSpatialField(field.Name); spatial = StaticIndexBase.CreateSpatialField(spatialField, inner.AsString()); } else if (inner.IsObject()) { var innerObject = inner.AsObject(); if (innerObject.HasOwnProperty("Lat") && innerObject.HasOwnProperty("Lng") && innerObject.TryGetValue("Lat", out var lat) && lat.IsNumber() && innerObject.TryGetValue("Lng", out var lng) && lng.IsNumber()) { spatialField = StaticIndexBase.GetOrCreateSpatialField(field.Name); spatial = StaticIndexBase.CreateSpatialField(spatialField, lat.AsNumber(), lng.AsNumber()); } else { continue; //Ignoring bad spatial field } } else { continue; //Ignoring bad spatial field } newFields += GetRegularFields(instance, field, spatial, indexContext, out _); continue; } } value = TypeConverter.ToBlittableSupportedType(propertyDescriptor.Value, flattenArrays: false, forIndexing: true, engine: documentToProcess.Engine, context: indexContext); newFields += GetRegularFields(instance, field, value, indexContext, out _); if (value is IDisposable toDispose) { // the value was converted to a lucene field and isn't needed anymore toDispose.Dispose(); } } return(newFields); }
protected override int GetFields <T>(T instance, LazyStringValue key, object doc, JsonOperationContext indexContext, IWriteOperationBuffer writeBuffer) { int newFields = 0; var document = (Document)doc; if (key != null) { Debug.Assert(document.LowerId == null || (key == document.LowerId)); instance.Add(GetOrCreateKeyField(key)); newFields++; } if (_reduceOutput) { instance.Add(GetReduceResultValueField(document.Data, writeBuffer)); newFields++; } foreach (var indexField in _fields.Values) { object value; if (indexField.Spatial is AutoSpatialOptions spatialOptions) { var spatialField = CurrentIndexingScope.Current.GetOrCreateSpatialField(indexField.Name); switch (spatialOptions.MethodType) { case AutoSpatialOptions.AutoSpatialMethodType.Wkt: if (BlittableJsonTraverserHelper.TryRead(_blittableTraverser, document, spatialOptions.MethodArguments[0], out var wktValue) == false) { continue; } value = StaticIndexBase.CreateSpatialField(spatialField, wktValue); break; case AutoSpatialOptions.AutoSpatialMethodType.Point: if (BlittableJsonTraverserHelper.TryRead(_blittableTraverser, document, spatialOptions.MethodArguments[0], out var latValue) == false) { continue; } if (BlittableJsonTraverserHelper.TryRead(_blittableTraverser, document, spatialOptions.MethodArguments[1], out var lngValue) == false) { continue; } value = StaticIndexBase.CreateSpatialField(spatialField, latValue, lngValue); break; default: throw new ArgumentOutOfRangeException(); } } else { if (BlittableJsonTraverserHelper.TryRead(_blittableTraverser, document, indexField.OriginalName ?? indexField.Name, out value) == false) { continue; } } newFields += GetRegularFields(instance, indexField, value, indexContext, out _); } return(newFields); }