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

希望对您有所帮助。