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 <Child> args) { foreach (var doc in args.Documents.Select(d => d.Value).Cast <IParentChildDocument>()) { doc.Discriminator = JoinField.Link <Child>(doc.ParentId); } return(Task.CompletedTask); }
[U] public void DuplicateJoinField() { /** * A class cannot contain more than one property of type JoinField, an exception is thrown in this case */ var dto = new BadDTO { SomeJoinField = JoinField.Link <MyOtherDTO>("8080"), AnotherJoinField = JoinField.Link <MyOtherDTO>("8081"), ParentName = "my-parent" }; Action resolve = () => Expect("8080").WhenInferringRoutingOn(dto); resolve.Should().Throw <ArgumentException>().WithMessage("BadDTO has more than one JoinField property"); /** unless you configure the ConnectionSettings to use an alternate property: */ WithConnectionSettings(x => x .DefaultMappingFor <BadDTO>(m => m .RoutingProperty(p => p.ParentName) ) ).Expect("my-parent").WhenInferringRoutingOn(dto); }
[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)); }
static void Main(string[] args) { _ElasticClient = new ElasticClient(GetConnection()); CreateIndexAndMappings(0, 5, -1); #region Documents List <BaseDocument> products = new List <BaseDocument>() { new Product() { Id = 1, Name = "IPhone 7", Price = 100, JoinField = "product", }, new Product() { Id = 2, Name = "IPhone 8", Price = 100, JoinField = "product" } }; var suppliers = new List <BaseDocument>() { new Supplier() { Id = 3, SupplierDescription = "Apple", Parent = 1, JoinField = JoinField.Link("supplier", 1), }, new Supplier() { Id = 4, SupplierDescription = "A supplier", Parent = 1, JoinField = JoinField.Link("supplier", 1) }, new Supplier() { Id = 5, SupplierDescription = "Another supplier", Parent = 2, JoinField = JoinField.Link("supplier", 2) } }; var stocks = new List <BaseDocument>() { new Stock() { Id = 6, Country = "USA", JoinField = JoinField.Link("stock", 1) }, new Stock() { Id = 7, Country = "UK", JoinField = JoinField.Link("stock", 2) }, new Stock() { Id = 8, Country = "Germany", JoinField = JoinField.Link("stock", 2) } }; var categoriees = new List <BaseDocument>() { new Category() { Id = 9, CategoryDescription = "Electronic", JoinField = JoinField.Link("category", 1) }, new Category() { Id = 10, CategoryDescription = "Smart Phone", JoinField = JoinField.Link("category", 2) }, new Category() { Id = 11, CategoryDescription = "Phone", JoinField = JoinField.Link("category", 2) } }; #endregion IndexDocuments(products); IndexChildDocuments(categoriees); IndexChildDocuments(stocks); IndexChildDocuments(suppliers); }
private static List <Package> GeneratePackages(int customerId) { int parentId = customerId; var packages = new List <Package> { new Package { OrderId = 1, PackageId = 1, Qty = 1, Weight = "10", CustomerJoinField = JoinField.Link <Package>(customerId) }, new Package { OrderId = 2, PackageId = 10, Qty = 10, Weight = "05", CustomerJoinField = JoinField.Link <Package>(customerId) }, new Package { OrderId = 3, PackageId = 5, Qty = 15, Weight = "03", CustomerJoinField = JoinField.Link <Package>(customerId) } }; return(packages); }
private static List <OrderItem> GenerateOrderItems(int customerId) { int parentId = customerId; var orderItems = new List <OrderItem> { new OrderItem { OrderId = 1, OrderItemId = 10, Quantity = 10, UnitPrice = 20.45m, CustomerJoinField = JoinField.Link <OrderItem>(customerId) }, new OrderItem { OrderId = 2, OrderItemId = 2, Quantity = 1, UnitPrice = 10, CustomerJoinField = JoinField.Link <OrderItem>(customerId) }, new OrderItem { OrderId = 3, OrderItemId = 1, Quantity = 2, UnitPrice = 2.45m, CustomerJoinField = JoinField.Link <OrderItem>(customerId) } }; return(orderItems); }
private static List <Order> GenerateOrders(int customerId) { int parentId = customerId; var orders = new List <Order> { new Order { OrderId = 1, Amount = 34.45m, CustomerId = customerId, CustomerJoinField = JoinField.Link <Order>(customerId) }, new Order { OrderId = 2, Amount = 20, CustomerId = customerId, CustomerJoinField = JoinField.Link <Order>(customerId) }, new Order { OrderId = 3, Amount = 10, CustomerId = customerId, CustomerJoinField = JoinField.Link <Order>(customerId) } // OrderId = 100, //// OrderDate = new DateTime(2017, 10, 11), // CustomerId = 1, // Amount = 23.45m, // OrderItems = new List<OrderItem> { // new OrderItem{ OrderItemId =1,Quantity = 2,UnitPrice = 12.23m}, // new OrderItem{ OrderItemId =2,Quantity = 1,UnitPrice = 10.23m} // }, // Packages = new List<Package>{ // new Package{ PackageId =1,OrderId = 1,Qty =2,Weight ="2.3"}, // new Package{ PackageId =2,OrderId = 1,Qty =1,Weight ="2.5"} // }, // CustomerJoinField = JoinField.Link<Order>(parentId) }; return(orders); }