【问题标题】:How to force NEST to use attribute mappings如何强制 NEST 使用属性映射
【发布时间】:2016-08-26 07:55:55
【问题描述】:

好的,如果这是一个愚蠢的问题,我很抱歉,但我花了一天时间浏览文档并尝试了 3 个不同的 NEST 版本,最终结果是相同的。

基本上,当我使用 Elasticsearch 的 REST api 为一个类型创建映射时,我可以在我的映射上使用 GET 请求,我会收到我想要的:

"properties": {
   "date": {
      "type": "date",
      "format": "basic_date"
   },
   "id": {
      "type": "long",
      "index": "no"
   },
   "name": {
      "type": "string"
   },
   "slug": {
      "type": "string",
      "index": "no"
   }
}

但是,如果我从头开始,并在 c# 中使用以下类:

[Number(Index = NonStringIndexOption.No)]
public long Id { get; set; }
[String(Name = "name")]
public string Name { get; set; }
[String(Name = "slug", Index = FieldIndexOption.No)]
public string Slug { get; set; }
[Date(Format = "dd-MM-yyyy", Index = NonStringIndexOption.No)]
public DateTime Date { get; set; }

并像这样创建和填充索引:

node = new Uri("http://localhost:9200");
settings = new ConnectionSettings(node);
settings.DefaultIndex("searchable-items");
//retrieve stuff from relational db
client.IndexMany(allItemsRetrievedFromRelDb);

我的类型默认如下(基本上忽略所有属性值,除了 Name=)

"date": {
   "type": "date",
   "format": "strict_date_optional_time||epoch_millis"
},
"id": {
   "type": "long"
},
"name": {
   "type": "string"
},
"slug": {
   "type": "string"
}

基本上我希望实现的是:

  1. “basic_date”类型的日期格式
  2. 只能分析和搜索“名称”
  3. 最终,“名称”的自定义分析器

我的问题是 - 我做错了什么,为什么 NEST 会忽略我在属性中添加的任何内容?当前代码是 v2.4.4,虽然我也尝试了 5.0.0 预发行版(那里的语法略有不同,但结果相同)。

【问题讨论】:

    标签: c# elasticsearch nest


    【解决方案1】:

    为了使属性映射生效,您需要在创建索引时使用 .CreateIndex() 或在创建索引之后并在索引任何文档之前使用 @987654326 告知 Elasticsearch @。

    这是一个演示使用 NEST 2.4.4 的示例

    void Main()
    {
        var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
        var defaultIndex = "searchable-items";
        var connectionSettings = new ConnectionSettings(pool)
                // specify the default index to use if
                // 1. no index is specified on the request
                // 2. no index can be inferred from the C# POCO type 
                .DefaultIndex(defaultIndex);;
    
        var client = new ElasticClient(connectionSettings);
    
        client.CreateIndex(defaultIndex, c => c
            .Mappings(m => m
                .Map<MyDocument>(mm => mm
                    // map MyDocument, letting
                    // NEST infer the mapping from the property types
                    // and attributes applied to them
                    .AutoMap()
                )
            )
        );
    
        var docs = new[] {
            new MyDocument
            {
                Id = 1,
                Name = "name 1",
                Date = new DateTime(2016,08,26),
                Slug = "/slug1"
            },
            new MyDocument
            {
                Id = 2,
                Name = "name 2",
                Date = new DateTime(2016,08,27),
                Slug = "/slug2"
            }
        };
    
        client.IndexMany(docs);
    }
    
    public class MyDocument
    {
        [Number(Index = NonStringIndexOption.No)]
        public long Id { get; set; }
        [String(Name = "name")]
        public string Name { get; set; }
        [String(Name = "slug", Index = FieldIndexOption.No)]
        public string Slug { get; set; }
        [Date(Format = "dd-MM-yyyy", Index = NonStringIndexOption.No)]
        public DateTime Date { get; set; }
    }
    

    The Automapping documentation 详细介绍了如何使用 the fluent APIthe visitor pattern (for applying conventions). 控制 POCO 类型的映射

    【讨论】:

    • 这解决了,谢谢。对于阅读本文的其他人,只需一句忠告 - 如果您不打算在 elasticsearch 结束时期望时间,请不要使用 DateTime 属性 - 它包含时间并且会中断请求。使用带有 Date 属性的字符串。
    • @nikovn - 我假设这意味着我也可以用数字或布尔属性标记字符串属性?如果我有一个用于导入 csv 文件的 DTO 类,并且想要在将字符串属性发送到 ElasticSearch 之前验证它是否确实具有数字值,我应该能够指定它是具有 Number 属性的数字而不是通过属性的类型来推断,对吗?
    • @FrankTzanabetis 您应该为要发送到 Elasticsearch 的值使用正确的 Elasticsearch 类型,例如发送"1" 是一个字符串,因此应该作为字符串进行索引,尽管将其显式映射到integer,但可以通过在映射coerce: true 上设置coerce: true 来强制Elasticsearch 将字符串强制转换为整数:elastic.co/guide/en/elasticsearch/reference/current/…。属性和流利的映射主要是为字段映射提供额外的选项;您可以按照您的要求做,但可能会为将来的问题做准备:)
    猜你喜欢
    • 1970-01-01
    • 2020-03-30
    • 2017-09-25
    • 2018-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-19
    相关资源
    最近更新 更多