2016-01-21 24 views
1

我有一個帶有UserID字段的類,其中包含郵件地址,我希望能夠在該字段中搜索完全匹配或部分郵件地址有一些排除。使用Nest創建自定義分析器(用於電子郵件地址)

例如,如果UserID包含「[email protected]」,我希望能夠搜索「[email protected]」,「john」和「doe」,但是「foo 「和」com「應該從索引中排除。

我試圖創建一個使用與排除的單詞列表停止過濾器自定義分析,並應用了多指標的屬性如下例:

using Nest; 
using System; 
using System.Collections.Generic; 

[ElasticType] 
public class ElasticUser { 
    [ElasticProperty(Index = FieldIndexOption.NotAnalyzed)] 
    public string UserID { get; set; } 
} 

class Program { 

    static void Main(string[] args) { 
     const string IndexName = "test_index"; 

     var settings = new ConnectionSettings(uri: new Uri("http://localhost:9200/"), defaultIndex: IndexName); 
     var client = new ElasticClient(settings); 

     // delete the index for the test 
     var deleteIndexResp = client.DeleteIndex(IndexName); 

     // create the custom filter and analyzer 
     var user_id_stop_filter = new StopTokenFilter { 
      Stopwords = new[] { "foo", "bar", "com" } 
     }; 
     var user_id_analyzer = new CustomAnalyzer { 
      Filter = new List<string> { 
       "user_id_stop_filter" 
      }, 
      Tokenizer = "letter" 
     }; 

     // create the index with the custom filter and analyzer 
     var createIndexResp = client.CreateIndex(IndexName, index => index 
      .Analysis(analysis => analysis 
       .TokenFilters(t => t 
        .Add("user_id_stop_filter", user_id_stop_filter)) 
       .Analyzers(a => a 
        .Add("user_id_analyzer", user_id_analyzer)))); 

     // add a mapping for the "ElasticUser" type 
     var putMapResp = client.Map<ElasticUser>(
      m => m.MapFromAttributes() 
      .Properties(properties => properties 
       .MultiField(multi => multi 
        .Name(p => p.UserID) 
        .Fields(fields => fields 
         .String(s => s 
          .Name(p => p.UserID) 
          .Index(FieldIndexOption.NotAnalyzed) 
         ) 
         .String(s => s 
          .Name(p => p.UserID.Suffix("searchable")) 
          .Analyzer("user_id_analyzer") 
         ) 
        ) 
       ) 
      )); 

     // add a couple of entries 
     client.Index(new ElasticUser { 
      UserID = "[email protected]" 
     }); 
     client.Index(new ElasticUser { 
      UserID = "[email protected]" 
     }); 
    } 

} 

然而,這並似乎不起作用,因爲我只能搜索完全匹配,但電子郵件地址不會被標記爲非字詞分裂。

我怎樣才能得到這個多指標工作描述?

當我嘗試運行此查詢,我沒有得到任何結果:

GET /test_index/elasticuser/_search 
{ 
    "query": { 
     "query_string": { 
      "query": "one" 
     } 
    } 
} 
+0

什麼版本您使用的是Elasticsearch和NEST/Elasticsearch.NET的哪個版本? –

回答

2

最簡單的方式來實現你想要的是簡單地在你的searchable場使用simple analyzer

... 
.String(s => s 
    .Name(p => p.UserID.Suffix("searchable")) 
    .Analyzer("simple")      <---- change this 
) 
... 

電子郵件將被標記爲任何非字母字符,您將能夠搜索johndoe

UPDATE

如果你想保持你的排除列表中,你絕對可以做到這一點。您可以保留現有的分析儀,但您需要使用lowercase tokenizer(即與simple分析儀中使用的相同),而不是letter

var user_id_analyzer = new CustomAnalyzer { 
     Filter = new List<string> { 
      "user_id_stop_filter" 
     }, 
     Tokenizer = "lowercase"   <--- change this 
    }; 

更新2

在純JSON,這裏是我

curl -XPUT localhost:9200/users -d '{ 
    "settings": { 
    "analysis": { 
     "analyzer": { 
     "email_analyzer": { 
      "type": "custom", 
      "tokenizer": "lowercase", 
      "filter": [ 
      "my_stop" 
      ] 
     } 
     }, 
     "filter": { 
     "my_stop": { 
      "type": "stop", 
      "stopwords": [ 
      "foo", 
      "bar", 
      "com" 
      ] 
     } 
     } 
    } 
    }, 
    "mappings": { 
    "user": { 
     "properties": { 
     "email": { 
      "type": "string", 
      "fields": { 
      "raw": { 
       "type": "string", 
       "index": "not_analyzed" 
      }, 
      "parts": { 
       "type": "string", 
       "analyzer": "email_analyzer" 
      } 
      } 
     } 
     } 
    } 
    } 
}' 

後來,當我分析[email protected],這裏是我得到

$ curl -XGET 'localhost:9200/users/_analyze?field=email.parts&pretty' -d '[email protected]' 
{ 
    "tokens" : [ { 
    "token" : "some", 
    "start_offset" : 0, 
    "end_offset" : 4, 
    "type" : "word", 
    "position" : 1 
    }, { 
    "token" : "one", 
    "start_offset" : 5, 
    "end_offset" : 8, 
    "type" : "word", 
    "position" : 2 
    } ] 
} 
+0

我還可以添加要排除到分析儀的單詞列表嗎?我原來的問題可能不太清楚,但我需要排除一些字。 –

+0

是的,我已經相應地更新了我的答案。 – Val

+0

對於「小寫」分詞器,如果我搜索「one」,我不會得到任何結果。只有當我插入像「some [email protected]」這樣的記錄時,我才能找到一些東西。看起來它不是在點上標記。 –

相關問題