【问题标题】:ElasticSearch 5 Sort by Keyword Field Case InsensitiveElasticSearch 5 按关键字字段不区分大小写排序
【发布时间】:2017-04-25 03:26:33
【问题描述】:

我们正在使用 ElasticSearch 5。 我有一个使用自定义分析器和以下映射的字段city

分析器

       "analysis": {
          "analyzer": {
            "lowercase_analyzer": {
              "filter": [
                "standard",
                "lowercase",
                "trim"
              ],
              "type": "custom",
              "tokenizer": "keyword"
            }
}

映射

  "city": {
    "type": "text",
    "analyzer": "lowercase_analyzer"
  }

我这样做是为了对 city 字段进行不区分大小写的排序。这是我尝试运行的示例查询

{ 
  "query": {
    "term": {
      "email": {
        "value": "some_email@test.com"
      }
    }
  },
"sort": [
    {
      "city": {
        "order": "desc"
      }
    }
  ]
}

这是我得到的错误:

"默认情况下禁用文本字段上的字段数据。设置 fielddata=true 在 [city] 上,通过反转 倒排索引。请注意,这可能会占用大量内存。”

我不想打开 FieldData 并在 ElasticSearch 中招致性能损失。我想要一个不区分大小写的Keyword 字段,以便我可以对其执行更有意义的聚合和排序。有没有办法做到这一点?

【问题讨论】:

    标签: elasticsearch nest


    【解决方案1】:

    是的,有一种方法可以做到这一点,使用multi_fields

    在 Elasticsearch 5.0 及以后版本中,string field types were split out 分为两种不同的类型,text 字段类型经过分析,可用于搜索,keyword 字段类型未分析,适用于排序、聚合和精确值匹配。

    在 Elasticsearch 5.0 中使用动态映射(即让 Elasticsearch 推断文档属性应该映射到的类型),一个 json 的string 属性映射到一个text 字段类型,子字段为“keyword” " 映射为 keyword 字段类型和设置 ignore_above:256

    使用 NEST 5.x 自动映射,您的 POCO 上的 string 属性将按照与 Elasticsearch 中的动态映射相同的方式自动映射,例如上面的映射。给定以下文件

    public class Document
    {
        public string Property { get; set; }
    }
    

    automapping it

    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var defaultIndex = "default-index";
    var connectionSettings = new ConnectionSettings(pool)
            .DefaultIndex(defaultIndex);
    
    var client = new ElasticClient(connectionSettings);
    
    client.CreateIndex(defaultIndex, c => c
        .Mappings(m => m
            .Map<Document>(mm => mm
                .AutoMap()
            )
        )
    );
    

    生产

    {
      "mappings": {
        "document": {
          "properties": {
            "property": {
              "fields": {
                "keyword": {
                  "ignore_above": 256,
                  "type": "keyword"
                }
              },
              "type": "text"
            }
          }
        }
      }
    }
    

    您现在可以使用property 使用Field(f =&gt; f.Property.Suffix("keyword") 进行排序。查看Field Inference 了解更多示例。

    keyword 字段类型默认启用doc_values,这意味着在索引时构建列数据结构,这就是提供高效排序和聚合的原因。

    要在创建索引时添加自定义分析器,我们可以像以前一样自动映射,但随后为我们想要使用.Properties() 控制映射的字段提供覆盖

    client.CreateIndex(defaultIndex, c => c
        .Settings(s => s
            .Analysis(a => a
                .Analyzers(aa => aa
                    .Custom("lowercase_analyzer", ca => ca
                        .Tokenizer("keyword")
                        .Filters(
                            "standard",
                            "lowercase",
                            "trim"
                        )
                    )
                )
            )
        )
        .Mappings(m => m
            .Map<Document>(mm => mm
                .AutoMap()
                .Properties(p => p
                    .Text(t => t
                        .Name(n => n.Property)
                        .Analyzer("lowercase_analyzer")
                        .Fields(f => f
                            .Keyword(k => k
                                .Name("keyword")
                                .IgnoreAbove(256)
                            )
                        )
                    )
                )
            )
        )
    );
    

    产生

    {
      "settings": {
        "analysis": {
          "analyzer": {
            "lowercase_analyzer": {
              "type": "custom",
              "filter": [
                "standard",
                "lowercase",
                "trim"
              ],
              "tokenizer": "keyword"
            }
          }
        }
      },
      "mappings": {
        "document": {
          "properties": {
            "property": {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              },
              "analyzer": "lowercase_analyzer"
            }
          }
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 2014-02-17
      • 1970-01-01
      • 2011-08-14
      • 1970-01-01
      • 2011-07-25
      • 1970-01-01
      相关资源
      最近更新 更多