【问题标题】:Elasticsearch NEST PUT Mapping to Add Field / PropertyElasticsearch NEST PUT 映射以添加字段/属性
【发布时间】:2019-07-26 14:28:45
【问题描述】:

我正在使用 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
          }
        }
      }
    ]
  }
}

【问题讨论】:

    标签: c# elasticsearch nest


    【解决方案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
    

    希望对您有所帮助。

    【讨论】:

    • 好的,成功了,谢谢!我希望这可以使文档映射与基本模型自动更新(即没有魔术字符串)保持同步。因此,例如,当我推出新版本的 API 时,索引映射将“自动更新”到 C# 模型,根据需要添加或删除任何字段。我认为我必须更像对待 SQL 数据库那样对待它,并让“更新脚本”作为新版本部署的一部分运行。
    猜你喜欢
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多