ElasticSearch(Nest) - 忽略撇号

时间:2017-06-16 22:05:05

标签: elasticsearch nest

我对Elasticsearch很新。我一直在尝试实现一个基本的搜索功能,可以忽略撇号。我找到了这一点documentation。对于实现,我使用了Nest库:

[ElasticsearchType]
public class MappingTest
{
  [Text(Analyzer = "english")]
  public string Title { get; set; }
}

索引/搜索:

var indexName = "testindex";
var connectionSettings =
    new ConnectionSettings(
        new Uri("https://url.com"))
        .DefaultIndex(indexName).EnableDebugMode();var client = new ElasticClient(connectionSettings);

if (client.IndexExists(Indices.All, descriptor => descriptor.Index(indexName)).Exists)
    client.DeleteIndex(indexName);

var response = client.CreateIndex(indexName, i => new CreateIndexDescriptor(indexName)
    .Mappings(ms => ms
        .Map<MappingTest>(m => m.AutoMap())
    ).Settings(s => s
        .Analysis(a => a
            .Analyzers(aa => aa
                .Custom("english", ca => ca
                    .Tokenizer("standard")
                    .Filters("english_possessive_stemmer", "lowercase")
                )
            )
            .TokenFilters(
                t => t.Stemmer("english_possessive_stemmer", d => d.Language("possessive_english")))
            .TokenFilters(
                t => t.Stemmer("english_stemmer", d => d.Language("english")))
            .TokenFilters(
                t => t.Stop("english_stop", d => d.StopWords("_english_")))
        )
    ));


var obj = new MappingTest() { Title = "Example's" };


var indexResponse = client.Index(obj);

var term = "example";

QueryContainer commonQuery =
    Query<MappingTest>.QueryString(qs => qs.Query(term).DefaultField(f => f.Title));

var searchResponse = client.Search<MappingTest>(s => s.Query(x => commonQuery));
var debug = searchResponse.DebugInformation;    

我尝试了几种方法,但每次都没有得到任何结果。我会提供一些帮助。

1 个答案:

答案 0 :(得分:0)

一些事情:

  1. 您无需指定自己的自定义"english"分析器,因为它已构建到Elasticsearch中。如果您想基于它 implement your own analyzer ,那么您需要按原样指定它。在您的情况下,我认为您不想指定自己的,因为您的自定义分析器仅使用english_possessive_stemmerlowercase令牌过滤器。
  2. 多次调用.TokenFilters()意味着只有最后一次通话获胜;调用通常在NEST中执行赋值,因此您需要

    .TokenFilters(t => t
        .Stemmer("english_possessive_stemmer", d => d.Language("possessive_english"))
        .Stemmer("english_stemmer", d => d.Language("english"))
        .Stop("english_stop", d => d.StopWords("_english_")))
    
  3. POCO属性Text上的Title属性决定了用于该字段的分析器

  4. 在刷新间隔结束(默认值为1秒)之后,索引文档才可用于搜索,并且新索引的文档将写入新段。在您的示例中,我怀疑您的搜索在文档可用于索引之前正在运行
  5. 我建议使用 Analyze API 来玩分析器。您可以为类型创建索引和映射,然后使用特定字段的映射

    分析一段文本
    void Main()
    {
        var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
        var defaultIndex = "default-index";
        var connectionSettings = new ConnectionSettings(pool)
            .DefaultIndex(defaultIndex)
            .PrettyJson()
            .EnableDebugMode(response =>
                {
                    if (response.RequestBodyInBytes != null)
                    {
                        Console.WriteLine(
                            $"{response.HttpMethod} {response.Uri} \n" +
                            $"{Encoding.UTF8.GetString(response.RequestBodyInBytes)}");
                    }
                    else
                    {
                        Console.WriteLine($"{response.HttpMethod} {response.Uri}");
                    }
    
                    Console.WriteLine();
    
                    if (response.ResponseBodyInBytes != null)
                    {
                        Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
                                 $"{Encoding.UTF8.GetString(response.ResponseBodyInBytes)}\n" +
                                 $"{new string('-', 30)}\n");
                    }
                    else
                    {
                        Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
                                 $"{new string('-', 30)}\n");
                    }
                });
    
        var client = new ElasticClient(connectionSettings);
    
        if (client.IndexExists(defaultIndex).Exists)
            client.DeleteIndex(defaultIndex);
    
        client.CreateIndex(defaultIndex, i => i
            .Mappings(ms => ms
                .Map<MappingTest>(m => m
                    .AutoMap()
                )
            )
        );
    
        client.Analyze(a => a
            .Index(defaultIndex)
            .Field<MappingTest>(f => f.Title)
            .Text("Example's")
        );
    }
    
    [ElasticsearchType]
    public class MappingTest
    {
        [Text(Analyzer = "english")]
        public string Title { get; set; }
    }
    

    您可以看到分析器返回Example's

    的以下标记
    {
      "tokens" : [
        {
          "token" : "exampl",
          "start_offset" : 0,
          "end_offset" : 9,
          "type" : "<ALPHANUM>",
          "position" : 0
        }
      ]
    }