当子文档的属性发生更改时,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; }
}
child 可以属于许多不同的 parent 。有什么办法可以将对子项的更改传播到包含该子项的所有父项?我正在使用C#的Nest客户端。
最佳答案
你在做什么不是很正确。
Child
属性设置为嵌套类型,但随后又对parent
和child
进行了索引。嵌套类型在嵌套的类型上建立索引,也就是说,表示
Child
上parent
属性的json被索引为父json文档的一部分。在Elasticsearch中可能有一个Parent/Child relationship,其中有一个 parent 有很多 child ,这听起来像您需要反转模型中的“ parent / child ”角色才能使用。
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; }
}
关于c# - ElasticSearch更新到子文档而不更新父文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41882928/