【问题标题】:ElasticSearch accent insensitive query with NEST C# client使用 NEST C# 客户端进行 ElasticSearch 重音不敏感查询
【发布时间】:2013-04-26 20:43:21
【问题描述】:

我正在尝试使用 NEST c# 客户端在 ElasticSearch 中进行一个没有重音的查询,我的数据有带有重音的葡萄牙语拉丁词。见下面代码:

var result = client.Search<Book>(s => s
    .From(0)
    .Size(20)
    .Fields(f => f.Title)
    .FacetTerm(f => f.OnField(of => of.Genre))
    .Query(q => q.QueryString(qs => qs.Query("sao")))
);

此搜索未找到任何内容。我在该索引上的数据包含许多标题,例如:“São Cristóvan”、“São Gonçalo”。

var settings = new IndexSettings();
settings.NumberOfReplicas = 1;
settings.NumberOfShards = 5;
settings.Analysis.Analyzers.Add("snowball", new Nest.SnowballAnalyzer { Language = "Portuguese" });
var idx5 = client.CreateIndex("idx5", settings);

如何使用 ElasticSearch 查询“sao”并找到“são”?

我认为必须创建具有正确属性的索引,但我已经尝试了许多设置。

或在原始模式下:

{ “idx”:{ “设置”:{ “index.analysis.filter.jus_stemmer.name”:“巴西人”, “index.analysis.filter.jus_stop._lang_”:“巴西” } } }

如何进行搜索并忽略重音符号?

感谢朋友,

【问题讨论】:

    标签: c# lucene elasticsearch nest


    【解决方案1】:

    查看解决方案:

    使用 putty 执行连接 elasticsearch 搜索:

    curl -XPOST 'localhost:9200/idx30/_close'
    
    curl -XPUT 'localhost:9200/idx30/_settings' -d '{
                "index.analysis.analyzer.default.filter.0": "standard",
                "index.analysis.analyzer.default.tokenizer": "standard",
                "index.analysis.analyzer.default.filter.1": "lowercase",
                "index.analysis.analyzer.default.filter.2": "stop",
                "index.analysis.analyzer.default.filter.3": "asciifolding",
                "index.number_of_replicas": "1"
    }'
    
    curl -XPOST 'localhost:9200/idx30/_open'
    

    将“idx30”替换为您的索引名称

    完成!

    【讨论】:

    • 是否可以恢复默认设置并删除过滤器?
    【解决方案2】:

    我偶然发现了这个帖子,因为我遇到了同样的问题。 这是使用 AsciiFolding Analyzer 创建索引的 NEST 代码:

    // Create the Client
    string indexName = "testindex";
    var uri = new Uri("http://localhost:9200");
    var settings = new ConnectionSettings(uri).SetDefaultIndex(indexName);
    var client = new ElasticClient(settings);
    // Create new Index Settings
    IndexSettings set = new IndexSettings();
    // Create a Custom Analyzer ...
    var an = new CustomAnalyzer();
    // ... based on the standard Tokenizer
    an.Tokenizer = "standard";
    // ... with Filters from the StandardAnalyzer
    an.Filter = new List<string>();
    an.Filter.Add("standard");
    an.Filter.Add("lowercase");
    an.Filter.Add("stop");
    // ... just adding the additional AsciiFoldingFilter at the end
    an.Filter.Add("asciifolding");
    // Add the Analyzer with a name
    set.Analysis.Analyzers.Add("nospecialchars", an);
    // Create the Index
    client.CreateIndex(indexName, set);
    

    现在您可以将您的实体映射到该索引(在创建索引后执行此操作很重要)

    client.MapFromAttributes<TestEntity>();
    

    下面是这样一个实体的样子:

    [ElasticType(Name = "TestEntity", DisableAllField = true)]
    public class TestEntity
    {
        public TestEntity(int id, string desc)
        {
            ID = id;
            Description = desc;
        }
    
        public int ID { get; set; }
    
        [ElasticProperty(Analyzer = "nospecialchars")]
        public string Description { get; set; }
    }
    

    你去吧,描述字段现在插入到索引中,没有重音符号。 如果您检查索引的映射,您可以对此进行测试:

    http://localhost:9200/testindex/_mapping
    

    然后应该看起来像:

    {
        testindex: {
            TestEntity: {
                _all: {
                    enabled: false
                },
                properties: {
                    description: {
                        type: "string",
                        analyzer: "nospecialchars"
                    },
                    iD: {
                        type: "integer"
                    }
                }
            }
        }
    }
    

    希望这会对某人有所帮助。

    【讨论】:

      【解决方案3】:

      您需要将ACSII Folding filter 合并到您的分析器中以完成此操作。这将意味着构建雪球分析器表单标记器和过滤器(除非nest 允许您将过滤器添加到非自定义分析器。但据我所知,ElasticSearch 没有)。

      SnowballAnalyzer 包含:

      • 标准标记器
      • 标准过滤器
      • (在此处添加 ASCII 折叠过滤器)
      • 小写过滤器
      • StopFilter(设置了适当的停用词)
      • SnowballFilter(使用适当的语言)
      • (或者在这里)

      我可能会尝试在 LowercaseFilter 之前添加 ASCIIFoldingFilter,尽管最好将其添加为最后一步(在 SnowballFilter 之后)。两种方式都试一下,看看哪个效果更好。我对 Protuguese 词干分析器的了解还不够,无法确定哪个是最好的。

      【讨论】:

      • 我尝试设置它,但它不起作用!。 settings.Analysis.Analyzers.Add("standard", new Nest.StandardAnalyzer()); settings.Analysis.TokenFilters.Add("ascii", new AsciiFoldingTokenFilter()); settings.Analysis.TokenFilters.Add("lowercase", new Nest.LowercaseTokenFilter()); settings.Analysis.Analyzers.Add("lang", new Nest.LanguageAnalyzer(Language.Brazilian) { StopWords = new List { "com", "quem" } }); settings.Analysis.Analyzers.Add("snowball", new Nest.SnowballAnalyzer { Language = "Brazilian" });
      • 您是否尝试在末尾使用 ASCIIFoldingFilter?真的不确定哪个更合适。它怎么不起作用?是不是和之前做的一样,抛出异常,不能得到结果?
      猜你喜欢
      • 1970-01-01
      • 2014-02-01
      • 2017-12-22
      • 2015-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-03
      相关资源
      最近更新 更多