protected IEnumerable <AbstractField> CreateField(string name, object value, CreateFieldOptions options)
        {
            // IMPORTANT: Do not delete this method, it is used by the indexes code when using CreateField

            options = options ?? CreateFieldOptions.Default;

            IndexFieldOptions allFields = null;
            var scope = CurrentIndexingScope.Current;

            if (scope.IndexDefinition is MapIndexDefinition mapIndexDefinition)
            {
                mapIndexDefinition.IndexDefinition.Fields.TryGetValue(Constants.Documents.Indexing.Fields.AllFields, out allFields);
            }

            var field = IndexField.Create(name, new IndexFieldOptions
            {
                Storage    = options.Storage,
                TermVector = options.TermVector,
                Indexing   = options.Indexing
            }, allFields);

            if (scope.CreateFieldConverter == null)
            {
                scope.CreateFieldConverter = new LuceneDocumentConverter(new IndexField[] { });
            }

            var result = new List <AbstractField>();

            scope.CreateFieldConverter.GetRegularFields(new StaticIndexLuceneDocumentWrapper(result), field, value, CurrentIndexingScope.Current.IndexContext);
            return(result);
        }
        protected IEnumerable <AbstractField> CreateField(string name, object value, bool stored = false, bool?analyzed = null)
        {
            FieldIndexing?index;

            switch (analyzed)
            {
            case true:
                index = FieldIndexing.Analyzed;
                break;

            case false:
                index = FieldIndexing.NotAnalyzed;
                break;

            default:
                index = null;
                break;
            }

            var field = IndexField.Create(name, new IndexFieldOptions
            {
                Storage    = stored ? FieldStorage.Yes : FieldStorage.No,
                TermVector = FieldTermVector.No,
                Indexing   = index
            }, null);

            if (_createFieldsConverter == null)
            {
                _createFieldsConverter = new LuceneDocumentConverter(new IndexField[] {});
            }

            return(_createFieldsConverter.GetRegularFields(field, value, CurrentIndexingScope.Current.IndexContext));
        }
Beispiel #3
0
    public IndexFieldBuilder AddField(string name)
    {
        var field = IndexField.Create(this, name);

        Instance.Fields.Add(field.Instance);
        return(field);
    }
Beispiel #4
0
        public void Convert_select_many_will_keep_doc_id()
        {
            var indexDefinition = new IndexDefinitionBuilder <Order>
            {
                Map = orders => from order in orders
                      from line in order.OrderLines
                      select new { line.ProductId }
#pragma warning disable CS0618 // Type or member is obsolete
            }.ToIndexDefinition(new DocumentConventions {
                PrettifyGeneratedLinqExpressions = false
            });

#pragma warning restore CS0618 // Type or member is obsolete

            indexDefinition.Name = "Index1";
            var index = IndexCompiler.Compile(indexDefinition);

            var map = index.Maps.Values.First().First();

            using (var context = JsonOperationContext.ShortTermSingleUse())
            {
                var results = map(new[]
                {
                    GetDocumentFromString(
                        @"
                {
                    '@metadata': {'@collection': 'Orders', '@id': 1},
                    'OrderLines': [{'ProductId': 2}, {'ProductId': 3}]
                }".Replace("\r\n", Environment.NewLine), context),
                    GetDocumentFromString(
                        @"
                {
                    '@metadata': {'@collection': 'Orders', '@id': 2},
                    'OrderLines': [{'ProductId': 5}, {'ProductId': 4}]
                }".Replace("\r\n", Environment.NewLine), context)
                }).Cast <object>().ToArray();

                var fields = index.OutputFields
                             .Select(x => IndexField.Create(x, new IndexFieldOptions(), null))
                             .ToList();

                var converter = new AnonymousLuceneDocumentConverter(fields, false);

                foreach (var result in results)
                {
                    using (var lazyStringValue = context.GetLazyString("docs/1"))
                    {
                        bool shouldSkip;
                        converter.SetDocument(lazyStringValue, result, context, out shouldSkip);
                        Assert.Equal("docs/1", converter.Document.Get(Constants.Documents.Indexing.Fields.DocumentIdFieldName, null));
                    }
                }
            }
        }
        private static IndexField[] GetFields(IndexDefinition definition, string[] outputFields)
        {
            IndexFieldOptions allFields;

            definition.Fields.TryGetValue(Constants.Indexing.Fields.AllFields, out allFields);

            var result = definition.Fields
                         .Where(x => x.Key != Constants.Indexing.Fields.AllFields)
                         .Select(x => IndexField.Create(x.Key, x.Value, allFields)).ToList();

            foreach (var outputField in outputFields)
            {
                if (definition.Fields.ContainsKey(outputField))
                {
                    continue;
                }

                result.Add(IndexField.Create(outputField, new IndexFieldOptions(), allFields));
            }

            return(result.ToArray());
        }
Beispiel #6
0
        protected IEnumerable <AbstractField> CreateField(string name, object value, bool stored = false, bool?analyzed = null)
        {
            // IMPORTANT: Do not delete this method, it is used by the indexes code when using LoadDocument
            FieldIndexing?index;

            switch (analyzed)
            {
            case true:
                index = FieldIndexing.Search;
                break;

            case false:
                index = FieldIndexing.Exact;
                break;

            default:
                index = null;
                break;
            }

            var field = IndexField.Create(name, new IndexFieldOptions
            {
                Storage    = stored ? FieldStorage.Yes : FieldStorage.No,
                TermVector = FieldTermVector.No,
                Indexing   = index
            }, null);

            if (_createFieldsConverter == null)
            {
                _createFieldsConverter = new LuceneDocumentConverter(new IndexField[] { });
            }

            var result = new List <AbstractField>();

            _createFieldsConverter.GetRegularFields(new StaticIndexLuceneDocumentWrapper(result), field, value, CurrentIndexingScope.Current.IndexContext);
            return(result);
        }
Beispiel #7
0
        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, LazyStringValue sourceDocumentId, 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 (sourceDocumentId != null)
            {
                instance.Add(GetOrCreateSourceDocumentIdField(sourceDocumentId));
                newFields++;
            }

            if (_storeValue)
            {
                var storedValue = JsBlittableBridge.Translate(indexContext,
                                                              documentToProcess.Engine,
                                                              documentToProcess);

                instance.Add(GetStoredValueField(storedValue, writeBuffer));
                newFields++;
            }

            if (TryGetBoostedValue(documentToProcess, out var boostedValue, out var documentBoost))
            {
                if (IsObject(boostedValue) == false)
                {
                    throw new InvalidOperationException($"Invalid boosted value. Expected object but got '{boostedValue.Type}' with value '{boostedValue}'.");
                }

                documentToProcess = boostedValue.AsObject();
            }

            foreach (var(property, propertyDescriptor) in documentToProcess.GetOwnProperties())
            {
                var propertyAsString = property.AsString();

                if (_fields.TryGetValue(propertyAsString, out var field) == false)
                {
                    field = _fields[propertyAsString] = IndexField.Create(propertyAsString, new IndexFieldOptions(), _allFields);
                }

                object value;
                float? propertyBoost = null;
                int    numberOfCreatedFields;
                var    actualValue = propertyDescriptor.Value;
                var    isObject    = IsObject(actualValue);
                if (isObject)
                {
                    if (TryGetBoostedValue(actualValue.AsObject(), out boostedValue, out propertyBoost))
                    {
                        actualValue = boostedValue;
                        isObject    = IsObject(actualValue);
                    }

                    if (isObject)
                    {
                        //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(propertyAsString, actualValue.AsObject(), field);
                        if (val != null)
                        {
                            if (val.IsObject() && val.AsObject().TryGetValue(SpatialPropertyName, 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);
                                numberOfCreatedFields = GetRegularFields(instance, field, CreateValueForIndexing(value, propertyBoost), indexContext, out _);

                                newFields += numberOfCreatedFields;

                                BoostDocument(instance, numberOfCreatedFields, documentBoost);

                                if (value is IDisposable toDispose1)
                                {
                                    // the value was converted to a lucene field and isn't needed anymore
                                    toDispose1.Dispose();
                                }

                                continue;
                            }
                        }

                        var objectValue = actualValue.AsObject();
                        if (objectValue.HasOwnProperty(SpatialPropertyName) && objectValue.TryGetValue(SpatialPropertyName, out var inner))
                        {
                            SpatialField spatialField;
                            IEnumerable <AbstractField> spatial;
                            if (inner.IsString())
                            {
                                spatialField = AbstractStaticIndexBase.GetOrCreateSpatialField(field.Name);
                                spatial      = AbstractStaticIndexBase.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 = AbstractStaticIndexBase.GetOrCreateSpatialField(field.Name);
                                    spatial      = AbstractStaticIndexBase.CreateSpatialField(spatialField, lat.AsNumber(), lng.AsNumber());
                                }
                                else
                                {
                                    continue; //Ignoring bad spatial field
                                }
                            }
                            else
                            {
                                continue; //Ignoring bad spatial field
                            }

                            numberOfCreatedFields = GetRegularFields(instance, field, CreateValueForIndexing(spatial, propertyBoost), indexContext, out _);

                            newFields += numberOfCreatedFields;

                            BoostDocument(instance, numberOfCreatedFields, documentBoost);

                            continue;
                        }
                    }
                }

                value = TypeConverter.ToBlittableSupportedType(actualValue, flattenArrays: false, forIndexing: true, engine: documentToProcess.Engine, context: indexContext);
                numberOfCreatedFields = GetRegularFields(instance, field, CreateValueForIndexing(value, propertyBoost), indexContext, out _);

                newFields += numberOfCreatedFields;

                BoostDocument(instance, numberOfCreatedFields, documentBoost);

                if (value is IDisposable toDispose)
                {
                    // the value was converted to a lucene field and isn't needed anymore
                    toDispose.Dispose();
                }
            }

            return(newFields);