private void IndexAll <TRoyal, TParent>(BulkDescriptor bulk, Func <IEnumerable <TRoyal> > create, TParent parent = null,
                                                Action <TRoyal> indexChildren = null
                                                )
            where TRoyal : class, IRoyal
            where TParent : class, IRoyal
        {
            var current = create();
            //looping twice horrible but easy to debug :)
            var royals = current.ToList();

            foreach (var royal in royals)
            {
                var royal1 = royal;
                if (parent == null)
                {
                    royal.Join = JoinField.Root <TRoyal>();
                }
                if (royal.Join == null)
                {
                    royal.Join = JoinField.Link <TRoyal, TParent>(parent);
                }
                bulk.Index <TRoyal>(i => i.Document(royal1).Index(_index).Type(RoyalType).Routing(parent == null ? royal.Name : parent.Name));
            }
            if (indexChildren == null)
            {
                return;
            }

            foreach (var royal in royals)
            {
                indexChildren(royal);
            }
        }
Beispiel #2
0
        protected Task OnDocumentsChanging(object sender, DocumentsChangeEventArgs <Parent> args)
        {
            foreach (var doc in args.Documents.Select(d => d.Value).Cast <IParentChildDocument>())
            {
                doc.Discriminator = JoinField.Root <Parent>();
            }

            return(Task.CompletedTask);
        }
Beispiel #3
0
        private static Customer GenerateCustomer()
        {
            var customer = new Customer()
            {
                CustomerId        = 1,
                FirstName         = "Rennish",
                LastName          = "Joseph",
                Email             = "*****@*****.**",
                CustomerJoinField = JoinField.Root <Customer>()
            };

            return(customer);
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var token = reader.ReadTokenWithDateParseHandlingNone();

            //in place because JsonConverter.Deserialize() only works on full json objects.
            //even though we pass type JSON.NET won't try the registered converter for that type
            //even if it can handle string tokens :(
            if (objectType == typeof(JoinField) && token.Type == JTokenType.String)
            {
                return(JoinField.Root(token.ToString(Formatting.None)));
            }

            using (var ms = token.ToStream())
                return(_builtInSerializer.Deserialize(objectType, ms));
        }
Beispiel #5
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var token = JToken.ReadFrom(reader);

            //in place because JsonConverter.Deserialize() only works on full json objects.
            //even though we pass type JSON.NET won't try the registered converter for that type
            //even if it can handle string tokens :(
            if (objectType == typeof(JoinField) && token.Type == JTokenType.String)
            {
                return(JoinField.Root(token.ToString()));
            }

            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(token.ToString())))
                return(_builtInSerializer.Deserialize(objectType, ms));
        }
        public void JoinFieldDeserializedCorrectly()
        {
            var doc = new MyDocument
            {
                Join = JoinField.Root("parent")
            };

            var tester   = SerializationTester.DefaultWithJsonNetSerializer;
            var response = tester.Client.IndexDocument(doc);

            tester.AssertSerialize(response.ApiCall.RequestBodyInBytes, new { join = "parent" });
            doc = tester.AssertDeserialize <MyDocument>(response.ApiCall.RequestBodyInBytes);

            doc.Join.Match(
                p => { p.Name.Should().Be("parent"); },
                c => throw new InvalidOperationException("should not be called"));
        }
        [U] public void CanGetRoutingFromJoinField()
        {
            /** here we link this instance of `MyOtherDTO` with its parent id `"8080"` */
            var dto = new MyOtherDTO
            {
                SomeJoinField = JoinField.Link <MyOtherDTO>("8080"),
                Id            = new Guid("D70BD3CF-4E38-46F3-91CA-FCBEF29B148E"),
                Name          = "x",
                OtherName     = "y"
            };

            Expect("8080").WhenInferringRoutingOn(dto);

            /**
             * Here we link this instance as the root (parent) of the relation. NEST infers that the default routing for this instance
             * should be the Id of the document itself.
             */
            dto = new MyOtherDTO
            {
                SomeJoinField = JoinField.Root <MyOtherDTO>(),
                Id            = new Guid("D70BD3CF-4E38-46F3-91CA-FCBEF29B148E"),
                Name          = "x",
                OtherName     = "y"
            };
            Expect("d70bd3cf-4e38-46f3-91ca-fcbef29b148e").WhenInferringRoutingOn(dto);

            /**
             * ==== Precedence of ConnectionSettings
             *
             * The routing property configured on `ConnectionSettings` always takes precedence.
             *
             */
            WithConnectionSettings(x => x
                                   .DefaultMappingFor <MyOtherDTO>(m => m
                                                                   .RoutingProperty(p => p.OtherName)
                                                                   )
                                   ).Expect("y").WhenInferringRoutingOn(dto);
        }
        public void Inferrence()
        {
            // hide
            var client = TestClient.GetInMemoryClient(c => c.DisableDirectStreaming().PrettyJson());
            var infer  = client.Infer;
            var parent = new MyParent {
                Id = 1337, MyJoinField = JoinField.Root <MyParent>()
            };

            infer.Routing(parent).Should().Be("1337");

            var child = new MyChild {
                Id = 1338, MyJoinField = JoinField.Link <MyChild>(parentId: "1337")
            };

            infer.Routing(child).Should().Be("1337");

            child = new MyChild {
                Id = 1339, MyJoinField = JoinField.Link <MyChild, MyParent>(parent)
            };
            infer.Routing(child).Should().Be("1337");

            /**
             * here we index `parent` and rather than fishing out the parent id by inspecting `parent` we just pass the instance
             * to `Routing` which can infer the correct routing key based on the JoinField property on the instance
             */
            var indexResponse = client.Index(parent, i => i.Routing(Routing.From(parent)));

            indexResponse.ApiCall.Uri.Query.Should().Contain("routing=1337");

            /**
             * The same goes for when we index a child, we can pass the instance directly to `Routing` and NEST will use the parent id
             * already specified on `child`. Here we use the static import `using static Nest.Infer` and it's `Route()` static method to
             * create an instance of `Routing`
             */
            indexResponse = client.Index(child, i => i.Routing(Route(child)));
            indexResponse.ApiCall.Uri.Query.Should().Contain("routing=1337");

            /** Wouldn't be handy if NEST does this automatically? It does! */
            indexResponse = client.IndexDocument(child);
            indexResponse.ApiCall.Uri.Query.Should().Contain("routing=1337");

            /** You can always override the default inferred routing though */
            indexResponse = client.Index(child, i => i.Routing("explicit"));
            indexResponse.ApiCall.Uri.Query.Should().Contain("routing=explicit");

            indexResponse = client.Index(child, i => i.Routing(null));
            indexResponse.ApiCall.Uri.Query.Should().NotContain("routing");

            /**
             * This works for both the fluent and object initializer syntax
             */

            var indexRequest = new IndexRequest <MyChild>(child);

            indexResponse = client.Index(indexRequest);
            indexResponse.ApiCall.Uri.Query.Should().Contain("routing=1337");

            /**
             * Its important to note that the routing is resolved at request time, not instantation time
             * here we update the `child`'s `JoinField` after already creating the index request for `child`
             */
            child.MyJoinField = JoinField.Link <MyChild>(parentId: "something-else");
            indexResponse     = client.Index(indexRequest);
            indexResponse.ApiCall.Uri.Query.Should().Contain("routing=something-else");
        }
        /**
         * ==== Indexing parents or children
         *
         * Now that we have our join field mapping set up on the index we can proceed to index parent and child documents.
         */

        [U] public void Indexing()
        {
            // hide
            var client = TestClient.GetInMemoryClient(c => c.DisableDirectStreaming().PrettyJson());

            /**
             * To mark a document with the relation name of the parent `MyParent` all of the following three ways are equivalent.
             *
             * In the first we explicitly call `JoinField.Root` to mark this document as the root of a parent child relationship namely
             * that of `MyParent`. In the following examples we rely on implicit conversion from `string` and `Type` to do the same.
             */
            var parentDocument = new MyParent
            {
                Id             = 1,
                ParentProperty = "a parent prop",
                MyJoinField    = JoinField.Root <MyParent>()
            };

            parentDocument = new MyParent
            {
                Id             = 1,
                ParentProperty = "a parent prop",
                MyJoinField    = typeof(MyParent)              // <1> this lets the join data type know this is a root document of type `myparent`
            };
            parentDocument = new MyParent
            {
                Id             = 1,
                ParentProperty = "a parent prop",
                MyJoinField    = "myparent"              // <1> this lets the join data type know this is a root document of type `myparent`
            };
            var indexParent = client.IndexDocument <MyDocument>(parentDocument);
            //json
            var expected = new
            {
                id             = 1,
                parentProperty = "a parent prop",
                myJoinField    = "myparent"
            };

            Expect(expected).FromRequest(indexParent);

            /**
             * Linking the child document to its parent follows a similar pattern.
             * Here we create a link by inferring the id from our parent instance `parentDocument`
             */
            var indexChild = client.IndexDocument <MyDocument>(new MyChild
            {
                MyJoinField = JoinField.Link <MyChild, MyParent>(parentDocument)
            });

            /**
             * or here we are simply stating this document is of type `mychild` and should be linked
             * to parent id 1 from `parentDocument`.
             */
            indexChild = client.IndexDocument <MyDocument>(new MyChild
            {
                Id          = 2,
                MyJoinField = JoinField.Link <MyChild>(1)
            });
            //json
            var childJson = new
            {
                id          = 2,
                myJoinField = new
                {
                    name   = "mychild",
                    parent = "1"
                }
            };

            Expect(childJson).FromRequest(indexChild);

            /**
             * The mapping already links `myparent` as the parent type so we only need to suply the parent id.
             * In fact there are many ways to create join field:
             */

            Expect("myparent").WhenSerializing(JoinField.Root(typeof(MyParent)));
            Expect("myparent").WhenSerializing(JoinField.Root(Relation <MyParent>()));
            Expect("myparent").WhenSerializing(JoinField.Root <MyParent>());
            Expect("myparent").WhenSerializing(JoinField.Root("myparent"));

            var childLink = new { name = "mychild", parent = "1" };

            Expect(childLink).WhenSerializing(JoinField.Link <MyChild>(1));
            Expect(childLink).WhenSerializing(JoinField.Link <MyChild, MyParent>(parentDocument));
            Expect(childLink).WhenSerializing(JoinField.Link("mychild", 1));
            Expect(childLink).WhenSerializing(JoinField.Link(typeof(MyChild), 1));
        }
Beispiel #10
0
        public static IEnumerable <Post> GetPosts(string path)
        {
            using (var stream = File.OpenRead(path))
                using (var reader = XmlReader.Create(stream))
                {
                    reader.ReadToDescendant("posts");
                    reader.ReadToDescendant("row");
                    do
                    {
                        var item         = (XElement)XNode.ReadFrom(reader);
                        var id           = int.Parse(item.Attribute("Id").Value, CultureInfo.InvariantCulture);
                        var postTypeId   = int.Parse(item.Attribute("PostTypeId").Value, CultureInfo.InvariantCulture);
                        var score        = int.Parse(item.Attribute("Score").Value, CultureInfo.InvariantCulture);
                        var body         = item.Attribute("Body")?.Value;
                        var creationDate = DateTimeOffset.Parse(item.Attribute("CreationDate").Value,
                                                                CultureInfo.InvariantCulture);
                        var commentCount = int.Parse(item.Attribute("CommentCount").Value, CultureInfo.InvariantCulture);
                        var ownerUserId  = item.Attribute("OwnerUserId") != null
                        ? int.Parse(item.Attribute("OwnerUserId").Value, CultureInfo.InvariantCulture)
                        : (int?)null;

                        var ownerDisplayName = item.Attribute("OwnerDisplayName")?.Value;
                        var lastEditorUserId = item.Attribute("LastEditorUserId") != null
                        ? int.Parse(item.Attribute("LastEditorUserId").Value, CultureInfo.InvariantCulture)
                        : (int?)null;

                        var lastEditDate = item.Attribute("LastEditDate") != null
                        ? DateTimeOffset.Parse(item.Attribute("LastEditDate").Value, CultureInfo.InvariantCulture)
                        : (DateTimeOffset?)null;

                        var lastActivityDate = item.Attribute("LastActivityDate") != null
                        ? DateTimeOffset.Parse(item.Attribute("LastActivityDate").Value, CultureInfo.InvariantCulture)
                        : (DateTimeOffset?)null;

                        switch (postTypeId)
                        {
                        case 1:
                            var title = item.Attribute("Title").Value;

                            var question = new Question
                            {
                                Id               = id,
                                ParentId         = JoinField.Root <Question>(),
                                AcceptedAnswerId = item.Attribute("AcceptedAnswerId") != null
                                    ? int.Parse(item.Attribute("AcceptedAnswerId").Value, CultureInfo.InvariantCulture)
                                    : (int?)null,
                                CreationDate          = creationDate,
                                Score                 = score,
                                ViewCount             = int.Parse(item.Attribute("ViewCount").Value, CultureInfo.InvariantCulture),
                                Body                  = body,
                                OwnerUserId           = ownerUserId,
                                OwnerDisplayName      = ownerDisplayName,
                                LastEditorUserId      = lastEditorUserId,
                                LastEditorDisplayName = item.Attribute("LastEditorDisplayName")?.Value,
                                LastEditDate          = lastEditDate,
                                LastActivityDate      = lastActivityDate,
                                Title                 = title,
                                TitleSuggest          = new CompletionField
                                {
                                    Input  = new[] { title },
                                    Weight = score < 0 ? 0 : score
                                },
                                Tags        = GetTags(item.Attribute("Tags")),
                                AnswerCount = int.Parse(item.Attribute("AnswerCount").Value,
                                                        CultureInfo.InvariantCulture),
                                CommentCount  = commentCount,
                                FavoriteCount = item.Attribute("FavoriteCount") != null
                                    ? int.Parse(item.Attribute("FavoriteCount").Value, CultureInfo.InvariantCulture)
                                    : 0,
                                CommunityOwnedDate = item.Attribute("CommunityOwnedDate") != null
                                    ? DateTimeOffset.Parse(item.Attribute("CommunityOwnedDate").Value,
                                                           CultureInfo.InvariantCulture)
                                    : (DateTimeOffset?)null
                            };

                            yield return(question);

                            break;

                        case 2:
                            var answer = new Answer
                            {
                                Id               = id,
                                ParentId         = JoinField.Link <Answer>(int.Parse(item.Attribute("ParentId").Value)),
                                CreationDate     = creationDate,
                                Score            = score,
                                Body             = body,
                                OwnerUserId      = ownerUserId,
                                OwnerDisplayName = ownerDisplayName,
                                LastEditorUserId = lastEditorUserId,
                                LastEditDate     = lastEditDate,
                                LastActivityDate = lastActivityDate,
                                CommentCount     = commentCount
                            };

                            yield return(answer);

                            break;
                        }
                    } while (reader.ReadToNextSibling("row"));
                }
        }
Beispiel #11
0
        public void Indexing()
        {
            // hide
            var client         = TestClient.GetInMemoryClient(c => c.DisableDirectStreaming().PrettyJson());
            var parentDocument = new MyParent
            {
                Id             = 1,
                ParentProperty = "a parent prop",
                MyJoinField    = JoinField.Root <MyParent>()             // <1> this lets the join data type know this is a root document of type `myparent`
            };
            var indexParent = client.IndexDocument <MyDocument>(parentDocument);
            //json
            var expected = new
            {
                id             = 1,
                parentProperty = "a parent prop",
                myJoinField    = "myparent"
            };

            Expect(expected).FromRequest(indexParent);

            /**
             * Note: you can simply implicitly convert from string to indicate the root name for the join field
             */
            JoinField parentJoinField = "aparent";

            /**
             * Linking the child document to its parent follows a similar pattern.
             * Here we create a link by inferring the id from our parent instance `parentDocument`
             */
            var indexChild = client.IndexDocument <MyDocument>(new MyChild
            {
                MyJoinField = JoinField.Link <MyChild, MyParent>(parentDocument)
            });

            /**
             * or here we are simply stating this document is of type `mychild` and should be linked
             * to parent id 1 from `parentDocument`.
             */
            indexChild = client.IndexDocument <MyDocument>(new MyChild
            {
                Id          = 2,
                MyJoinField = JoinField.Link <MyChild>(1)
            });
            //json
            var childJson = new
            {
                id          = 2,
                myJoinField = new
                {
                    name   = "mychild",
                    parent = "1"
                }
            };

            Expect(childJson).FromRequest(indexChild);

            /**
             * The mapping already links `myparent` as the parent type so we only need to suply the parent id.
             * In fact there are many ways to create join field:
             */

            Expect("myparent").WhenSerializing(JoinField.Root(typeof(MyParent)));
            Expect("myparent").WhenSerializing(JoinField.Root(Relation <MyParent>()));
            Expect("myparent").WhenSerializing(JoinField.Root <MyParent>());
            Expect("myparent").WhenSerializing(JoinField.Root("myparent"));

            var childLink = new { name = "mychild", parent = "1" };

            Expect(childLink).WhenSerializing(JoinField.Link <MyChild>(1));
            Expect(childLink).WhenSerializing(JoinField.Link <MyChild, MyParent>(parentDocument));
            Expect(childLink).WhenSerializing(JoinField.Link("mychild", 1));
            Expect(childLink).WhenSerializing(JoinField.Link(typeof(MyChild), 1));
        }