2017-01-26 7 views
0

子文書のプロパティが変更されたときに、すべての親文書を自動的に更新する方法はありますか?たぶん、私はElasticSearchをどのように使用しているかについての道のりです。コード:親文書を更新していない子文書へのElasticSearch更新

 var child = new Child 
     { 
      Id = Guid.NewGuid(), 
      Name = "Child" 
     }; 

     var parent = new Parent 
     { 
      Id = Guid.NewGuid(), 
      Name = "Parent", 
      Child = child 
     }; 

     var nestedResponse = client.CreateIndex("index", i => i 
      .Mappings(m => m 
       .Map<Parent>(map => map 
        .AutoMap() 
        .Properties(ps => ps 
         .Nested<Child>(n => n 
          .Name(p => p.Child) 
          .AutoMap() 
         ) 
        ) 
       ) 
      ) 
     ); 

     var indexResult = client.Index<Parent>(parent); 
     indexResult = client.Index<Child>(child); 

     var reloadedParent = client.Get<Parent>(parent.Id.ToString()).Source; 
     var childName = reloadedParent.Child.Name; 
     child.Name = "child changed"; 
     var updateRequest = new UpdateRequest<Child, Child>("index", typeof(Child), child.Id); 
     updateRequest.Doc = child; 

     var reindexResult = client.Update<Child>(updateRequest); 

     var reloadedParentAfterChildChange = client.Get<Parent>(parent.Id.ToString()).Source; 
     var childChangedName = reloadedParentAfterChildChange.Child.Name; 

     Assert.AreEqual(child.Name, childChangedName); 

    } 
} 

public class Parent 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public Child Child { get; set; } 
} 

public class Child 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
} 

子供は多くの異なる親に属することができます。子への変更を子を含むすべての親に伝播させる方法はありますか?私はC#からNestクライアントを使用しています。

答えて

1

あなたがやっていることは間違いです。マッピングで

  1. 、ネストされたタイプとしてChildプロパティを設定したが、その後、インデックスの両方parentchild

    ネストされた型は、それがparentChildプロパティを表すJSONが親JSON文書の一部として索引付けされている、それはネストさされたタイプにインデックス付けされます。

    1つの親から多数の子を持つParent/Child relationshipをElasticsearchに含めることができます。使用するモデル内の親子関係を逆転する必要があるようです。インデックス後

  2. は、あなたが親の子の子の名前を変更、parent文書のソースを取得したが、その後子供とparentを更新ずにインデックスされている子の文書、を更新します。

    多くのドキュメントで同じネストされたドキュメント値を使用できますが、これらのドキュメント間には関係がないため、値を更新するには各ドキュメントを更新する必要があります。これはUpdate By Query APIで行うことができます。

ここで実証するです。とき子供ができ生産では、おそらくその少し厄介...働く

void Main() 
{ 
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); 
    var defaultIndex = "default-index"; 
    var connectionSettings = new ConnectionSettings(pool) 
      .DefaultIndex(defaultIndex) 
      .PrettyJson() 
      .DisableDirectStreaming() 
      .OnRequestCompleted(response => 
       { 
        // log out the request 
        if (response.RequestBodyInBytes != null) 
        { 
         Console.WriteLine(
          $"{response.HttpMethod} {response.Uri} \n" + 
          $"{Encoding.UTF8.GetString(response.RequestBodyInBytes)}"); 
        } 
        else 
        { 
         Console.WriteLine($"{response.HttpMethod} {response.Uri}"); 
        } 

        Console.WriteLine(); 

        // log out the response 
        if (response.ResponseBodyInBytes != null) 
        { 
         Console.WriteLine($"Status: {response.HttpStatusCode}\n" + 
           $"{Encoding.UTF8.GetString(response.ResponseBodyInBytes)}\n" + 
           $"{new string('-', 30)}\n"); 
        } 
        else 
        { 
         Console.WriteLine($"Status: {response.HttpStatusCode}\n" + 
           $"{new string('-', 30)}\n"); 
        } 
       }); 

    var client = new ElasticClient(connectionSettings); 

    if (client.IndexExists(defaultIndex).Exists) 
     client.DeleteIndex(defaultIndex); 

    var child = new Child 
    { 
     Id = Guid.NewGuid(), 
     Name = "Child" 
    }; 

    var parent = new Parent 
    { 
     Id = Guid.NewGuid(), 
     Name = "Parent", 
     Child = child 
    }; 

    var anotherParent = new Parent 
    { 
     Id = Guid.NewGuid(), 
     Name = "Another Parent", 
     Child = child 
    }; 

    var nestedResponse = client.CreateIndex(defaultIndex, i => i 
     .Mappings(m => m 
      .Map<Parent>(map => map 
       .AutoMap() 
       .Properties(ps => ps 
        .String(s => s 
         .Name(nn => nn.Id) 
         .NotAnalyzed() 
        ) 
        .Nested<Child>(n => n 
         .Name(p => p.Child) 
         .AutoMap() 
         .Properties(p => p 
          .String(s => s 
           .Name(nn => nn.Id) 
           .NotAnalyzed() 
          ) 
         ) 
        ) 
       ) 
      ) 
     ) 
    ); 

    var indexResult = client.Index<Parent>(parent); 
    indexResult = client.Index<Parent>(anotherParent); 

    var fetchedParent = client.Get<Parent>(parent.Id).Source; 
    var fetchedAnotherParent = client.Get<Parent>(anotherParent.Id).Source; 

    client.Refresh(defaultIndex); 

    var update = client.UpdateByQuery<Parent>(u => u 
     .Query(q => q 
      .Nested(n => n 
       .Path(p => p.Child) 
       .Query(qq => qq 
        .Term(t => t.Child.Id, child.Id) 
       ) 
      ) 
     ) 
     .Script("ctx._source.child.name='New Child Name'") 
     .Conflicts(Conflicts.Abort) 
     .WaitForCompletion() 
     .Refresh() 
    ); 

    fetchedParent = client.Get<Parent>(parent.Id).Source; 
    fetchedAnotherParent = client.Get<Parent>(anotherParent.Id).Source; 
} 


public class Parent 
{ 
    public Guid Id { get; set; } 

    public string Name { get; set; } 

    public Child Child { get; set;} 
} 

public class Child 
{ 
    public Guid Id { get; set; } 

    public string Name { get; set; } 
} 
+0

おかげで、など、直接ストリーミングを無効にしたいすべてのリクエスト/レスポンスをログアウトし、各操作の後にリフレッシュを呼び出すことはありませんさまざまな種類の親に属しています...クライアントがプロジェクト、注文などに属しているように – user10479

+0

Elasticsearchは、検索、分析、大規模なデータを大規模なパフォーマンスで処理するのに非常に優れています。ただし、リレーショナルデータストアではないため、データのモデリング方法を再設計する必要があります。 –

関連する問題