Elasticsearch NEST PUT 映射添加字段 / 属性
Elasticsearch NEST PUT Mapping to Add Field / Property
我正在使用 NEST Suggest.Completion 查询来提供提示性搜索。我已经在索引中有数据并想添加一个新字段 "IsActive" 以允许我禁止某些文档出现在建议中。
我认为 NEST Map<>
方法会在 运行 时将新字段添加到索引中的所有现有文档,但事实并非如此。有什么方法可以让它像那样工作吗?
我正在使用 Elasticsearch 6.8.0。
带有新字段的我的对象
[ElasticsearchType(
IdProperty = "search"
)]
public class SearchCompletion
{
public string search { get; set; }
/// <summary>
/// Use this field for aggregations and sorts
/// </summary>
[Keyword]
public string search_keyword { get; set; }
public bool isActive { get; set; } // <---- This is the new field
/// <summary>
/// To use for sorting results
/// since you can't sort by the Completionfield.Weight
/// property for some reason
/// </summary>
public int weight { get; set; }
public CompletionField suggest { get; set; }
}
重新应用映射的方法
public static void MapSearchCompletions(ElasticClient client, string index)
{
var mapResponse = client.Map<SearchCompletion>(m => m
.Index(index)
.AutoMap()
); //re-apply the index mapping
}
PUT请求
PUT /local.project.tests.searchcompletions/searchcompletion/_mapping
{
"properties": {
"search": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"search_keyword": {
"type": "keyword"
},
"isActive": {
"type": "boolean"
},
"weight": {
"type": "integer"
},
"suggest": {
"type": "completion"
}
}
}
映射后查询索引的结果
GET /local.project.tests.searchcompletions/searchcompletion/_search
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "local.project.tests.searchcompletions",
"_type": "searchcompletion",
"_id": "the",
"_score": 1,
"_source": {
"search": "the",
"search_keyword": "the",
"weight": 1,
"suggest": {
"input": [
"the",
"the"
],
"weight": 1
}
}
}
]
}
}
是的,更新映射不会更改现有文档。为此,您可以使用 update_by_query API.
var updateByQueryResponse = await client.UpdateByQueryAsync<Document>(u => u
.Query(q => q.MatchAll())
.Script("ctx._source.isActive = true")
.Refresh());
完整示例如下:
class Program
{
public class Document
{
public int Id { get; set; }
public bool IsActive { get; set; }
}
static async Task Main(string[] args)
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var connectionSettings = new ConnectionSettings(pool);
connectionSettings.DefaultIndex("documents");
var client = new ElasticClient(connectionSettings);
var deleteIndexResponse = await client.Indices.DeleteAsync("documents");
var createIndexResponse = await client.Indices.CreateAsync("documents", d => d
.Map(m => m.AutoMap<Document>()));
var indexDocument = await client.IndexDocumentAsync(new Document {Id = 1});
var refreshAsync = client.Indices.RefreshAsync();
var putMappingResponse = await client.MapAsync<Document>(m => m
.AutoMap());
var updateByQueryResponse = await client.UpdateByQueryAsync<Document>(u => u
.Query(q => q.MatchAll())
.Script("ctx._source.isActive = true")
.Refresh());
var response = await client.GetAsync<Document>(1);
Console.WriteLine(response.Source.IsActive);
}
}
打印:
True
希望对您有所帮助。
我正在使用 NEST Suggest.Completion 查询来提供提示性搜索。我已经在索引中有数据并想添加一个新字段 "IsActive" 以允许我禁止某些文档出现在建议中。
我认为 NEST Map<>
方法会在 运行 时将新字段添加到索引中的所有现有文档,但事实并非如此。有什么方法可以让它像那样工作吗?
我正在使用 Elasticsearch 6.8.0。
带有新字段的我的对象
[ElasticsearchType(
IdProperty = "search"
)]
public class SearchCompletion
{
public string search { get; set; }
/// <summary>
/// Use this field for aggregations and sorts
/// </summary>
[Keyword]
public string search_keyword { get; set; }
public bool isActive { get; set; } // <---- This is the new field
/// <summary>
/// To use for sorting results
/// since you can't sort by the Completionfield.Weight
/// property for some reason
/// </summary>
public int weight { get; set; }
public CompletionField suggest { get; set; }
}
重新应用映射的方法
public static void MapSearchCompletions(ElasticClient client, string index)
{
var mapResponse = client.Map<SearchCompletion>(m => m
.Index(index)
.AutoMap()
); //re-apply the index mapping
}
PUT请求
PUT /local.project.tests.searchcompletions/searchcompletion/_mapping
{
"properties": {
"search": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"search_keyword": {
"type": "keyword"
},
"isActive": {
"type": "boolean"
},
"weight": {
"type": "integer"
},
"suggest": {
"type": "completion"
}
}
}
映射后查询索引的结果
GET /local.project.tests.searchcompletions/searchcompletion/_search
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "local.project.tests.searchcompletions",
"_type": "searchcompletion",
"_id": "the",
"_score": 1,
"_source": {
"search": "the",
"search_keyword": "the",
"weight": 1,
"suggest": {
"input": [
"the",
"the"
],
"weight": 1
}
}
}
]
}
}
是的,更新映射不会更改现有文档。为此,您可以使用 update_by_query API.
var updateByQueryResponse = await client.UpdateByQueryAsync<Document>(u => u
.Query(q => q.MatchAll())
.Script("ctx._source.isActive = true")
.Refresh());
完整示例如下:
class Program
{
public class Document
{
public int Id { get; set; }
public bool IsActive { get; set; }
}
static async Task Main(string[] args)
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var connectionSettings = new ConnectionSettings(pool);
connectionSettings.DefaultIndex("documents");
var client = new ElasticClient(connectionSettings);
var deleteIndexResponse = await client.Indices.DeleteAsync("documents");
var createIndexResponse = await client.Indices.CreateAsync("documents", d => d
.Map(m => m.AutoMap<Document>()));
var indexDocument = await client.IndexDocumentAsync(new Document {Id = 1});
var refreshAsync = client.Indices.RefreshAsync();
var putMappingResponse = await client.MapAsync<Document>(m => m
.AutoMap());
var updateByQueryResponse = await client.UpdateByQueryAsync<Document>(u => u
.Query(q => q.MatchAll())
.Script("ctx._source.isActive = true")
.Refresh());
var response = await client.GetAsync<Document>(1);
Console.WriteLine(response.Source.IsActive);
}
}
打印:
True
希望对您有所帮助。