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); } }
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); }
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)); }
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)); }
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")); } }
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)); }