2016-05-26 3 views
1

私はelasticsearch初心者です。nest c#clientを使用してelasticsearchでアクセントを無視した検索を行う方法は?

public class A 
{ 
    public string name; 
} 

そして、我々は"エーズ""Ayseの"のような名前を持つ2つの文書を持っている:

たちは、このようなクラスを考えてみましょう。

今、名前をアクセント付きで保存できるようにしたいが、アクセントの影響を受けないクエリの結果をアクセントに敏感な結果として受け取るようにしたい場合は、。 EXのために

:私は「Ayseの」または「エーズ」を検索する場合、彼らは(アクセントで)保存されたとして、それが「エーズ」の両方と「Ayseの」を返す必要があります。

「Ayse」を検索すると「Ayse」だけが返されますが、結果として「Ayşe」も表示されます。

私がelasticsearchのドキュメントをチェックしたとき、折りたたまれたプロパティがそれを達成するために使用される必要があることがわかりました。しかし、ネストの属性や関数を使ってどのように行うのか理解できませんでした。

私は現在、マッピングを作成するためにオートマップを使用しています。可能であれば、引き続き使用できるようにしたいと考えています。

私は現在2日間の回答を探していますが、まだそれを把握できませんでした。

変更する必要はありますか?コードサンプルを提供できますか?

ありがとうございます。

EDIT 1:

私は、プロパティのサブフィールドとサブフィールドに対する用語ベースのクエリでachive結果を作成するためのアナライザを使用する方法を考え出しました。

今、私はマルチフィールド検索を行うことができますが、はフルテキスト検索でサブフィールドを含める方法はありますか?

ありがとうございます。

+0

https://www.elastic.co/guide/en/elasticsearch/reference行われます/current/analysis-synonym-tokenfilter.htmlこれは助けてくれるでしょう –

+0

私はhttps://www.elastic.co/guide/en/elasticsearch/guide/current/asciifolding-token-filter.htmlのようなものが必要だと思いますが、私はそれは.netと一緒に使用する方法を理解していないので、名前が1つしかなく、name.foldedを持たないためです。だから私は名前を照会することはできません。linqによって折り畳まれています。また、私の実際の状況では、クエリのプロパティがたくさんあるので、 'Ayese'のような元の値だけを格納し、 'Ayse'のようなクエリを取得し、結果として 'Ayşe'を取得する方法があるのだろうかと思います。 Nest.Stringには、AnalyzerとSearchAnalyzerという2つの属性パラメータがあります。私はそれについて質問するたくさんの質問があります – zokkan

+0

@DhruvPal私はすべての可能性を記録していないので、あなたが言及した方法は私の状況にとって有用ではないようです。 – zokkan

答えて

2

あなたは、インデックス時にテキストのconfigure an analyzer to perform analysis、インデックスがこのmulti_fieldは、問合せ時に使用するだけでなく、オリジナルのソースを維持するためには、結果に返されることができます。あなたの質問に基づいて、asciifolding token filterを使用してインデックスと検索時にASCII文字に変換するカスタムアナライザーが必要なように思えます。インデックスが作成されたときに行うことができるカスタム・アナライザを設定する次の文書

public class Document 
{ 
    public int Id { get; set;} 
    public string Name { get; set; } 
} 

考える

。我々はまた、私は1つのシャードなしのレプリカ(ご使用の環境のためにこれを変更したい場合があります)を使用して索引を作成しました

client.CreateIndex(documentsIndex, ci => ci 
    .Settings(s => s 
     .NumberOfShards(1) 
     .NumberOfReplicas(0) 
     .Analysis(analysis => analysis 
      .TokenFilters(tokenfilters => tokenfilters 
       .AsciiFolding("folding-preserve", ft => ft 
        .PreserveOriginal() 
       ) 
      ) 
      .Analyzers(analyzers => analyzers 
       .Custom("folding-analyzer", c => c 
        .Tokenizer("standard") 
        .Filters("standard", "folding-preserve") 
       ) 
      ) 
     ) 
    ) 
    .Mappings(m => m 
     .Map<Document>(mm => mm 
      .AutoMap() 
      .Properties(p => p 
       .String(s => s 
        .Name(n => n.Name) 
        .Fields(f => f 
         .String(ss => ss 
          .Name("folding") 
          .Analyzer("folding-analyzer") 
         ) 
        ) 
        .NotAnalyzed() 
       ) 
      ) 
     ) 
    ) 
); 

ここで同時にマッピングを指定することができ、およびカスタム・アナライザ、folding-analyzerを作成しましたトークンフィルタstandardとトークンフィルタfolding-preserveと一緒に標準のトークナイザを使用して、折り畳まれたトークンに加えて元のトークンを格納します(詳細は1分後に役立ちます)。

私はまたfolding-analyzerで分析されるデフォルトのフィールドnot_analyzed(集計に便利)と.foldingサブフィールドで、multi_fieldとしてNameプロパティをマッピングし、Documentタイプをマッピングしました。元のソースドキュメントは、デフォルトではElasticsearchによって保存されます。

今すぐインデックス一部の文書最後に

client.Index<Document>(new Document { Id = 1, Name = "Ayse" }); 
client.Index<Document>(new Document { Id = 2, Name = "Ayşe" }); 

// refresh the index after indexing to ensure the documents just indexed are 
// available to be searched 
client.Refresh(documentsIndex); 

は、エーズ

var response = client.Search<Document>(s => s 
    .Query(q => q 
     .QueryString(qs => qs 
      .Fields(f => f 
       .Field(c => c.Name.Suffix("folding")) 
      ) 
      .Query("Ayşe") 
     ) 
    ) 
); 

利回り

{ 
    "took" : 2, 
    "timed_out" : false, 
    "_shards" : { 
    "total" : 1, 
    "successful" : 1, 
    "failed" : 0 
    }, 
    "hits" : { 
    "total" : 2, 
    "max_score" : 1.163388, 
    "hits" : [ { 
     "_index" : "documents", 
     "_type" : "document", 
     "_id" : "2", 
     "_score" : 1.163388, 
     "_source" : { 
     "id" : 2, 
     "name" : "Ayşe" 
     } 
    }, { 
     "_index" : "documents", 
     "_type" : "document", 
     "_id" : "1", 
     "_score" : 0.3038296, 
     "_source" : { 
     "id" : 1, 
     "name" : "Ayse" 
     } 
    } ] 
    } 
} 

ここで強調表示するには、2つのものを探してみましょう

はまず、_sourceはあなたが例

string.Join(",", response.Documents.Select(d => d.Name)); 

のために、元の名前を取得します、response.Documentsを使用してElasticsearchになるように送信されたオリジナルのテキストが含まれている第二に、あなたに「エーズ、Ayseの」

を与えるだろう、 asciifoldingトークンフィルタに元のトークンを保存したことを覚えていますか?そうすることで、アクセントに無関係に一致するように分析するクエリを実行できますが、スコアリングについてはアクセントの感度も考慮に入れます。上記の例では、のスコアエーズエーズとAyseののみAyseのながら前者インデックス付けされるトークンがために索引付けされているため、エーズはエーズと一致Ayseのよりも高い一致します後者。分析を受けるクエリがNameプロパティに対して実行された場合、クエリはfolding-analyzerで分析され、マッチの検索が

Index time 
---------- 

document 1 name: Ayse --analysis--> Ayse 

document 2 name: Ayşe --analysis--> Ayşe, Ayse 


Query time 
----------- 

query_string query input: Ayşe --analysis--> Ayşe, Ayse 

search for documents with tokens for name field matching Ayşe or Ayse 
+0

こんにちは@RossCam、この例に問題があります。「Ayşe」を検索すると検索結果が表示されますが、「Ayse」は検索しません。私はカスタムアナライザとデフォルトのものでクエリのアナライザ機能を使用しようとしましたが、運はありません。この問題は、私の元の問題と同じ問題です。http://stackoverflow.com/questions/37524988/indexing-and-full-text-searching-in-elasticsearch-without-dialitics-using-c-shar – zokkan

+0

いつものように、ありがとうあなたの詳細な答えはラスです。しかし、私は "ayse"の検索結果が戻って来ないので、これを答えとして受け入れていません。 – zokkan

+0

これは、NEST 2.3.1をElasticsearch 2.3.2に対して使用しています。もう一度確実にテストしました。あなたが使っているNESTのバージョンとElasticsearchのバージョンは何ですか?あなたのインデックスのマッピングやアナライザはどのように見えますか? 'curl -XGET"を実行すると、http:// localhost:9200/{index-name} "'あなたは何を得ますか? –

関連する問題