2017-03-02 141 views
0

我正在使用Microsoft SQL Server Management Studio和ElasticSearch 2.3.4與ElasticSearch-jdbc-2.3.4.1,並且我將ES鏈接到我的mssql服務器。一切工作正常,但是當我在我的MVC程序上使用NEST進行查詢時,結果爲空。當我把我的search屬性中的空字符串,我得到的元素,但是當我嘗試用一​​些過濾器填充它,我得到一個空的結果。有人可以幫我嗎?提前致謝。Elasticsearch查詢與NEST不起作用

C#:

const string ESServer = "http://localhost:9200"; 
ConnectionSettings settings = new ConnectionSettings(new Uri(ESServer)); 
settings.DefaultIndex("tiky"); 
settings.MapDefaultTypeNames(map => map.Add(typeof(DAL.Faq), "faq")); 
ElasticClient client = new ElasticClient(settings); 

var response = client.Search<DAL.Faq>(s => s.Query(q => q.Term(x => x.Question, search))); 

var result = response.Documents.ToList(); 

DAL:DAL

郵差:PostMan

PS:我跟着this guide創建它

編輯:

指數映射:Index Mapping

+0

可以分享索引映射嗎? 'http:// localhost:9200/tiky/_mapping' – Rob

+0

@Rob當然,我已更新問題 –

+0

分析問題字段,並使用術語查詢與not_analyzed字段一起工作。你可以閱讀更多關於[這裏](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html)。 – Rob

回答

2

有一對夫婦的事情,我可以看到,這可能有所幫助:

  1. 默認情況下,NEST駱駝案件POCO屬性名稱序列化時它們作爲請求中查詢JSON的一部分,因此x => x.Question將序列化爲"question"。然而,看看你的映射,Elasticsearch中的字段名稱是Pascal,所以客戶正在做的事情與Elasticsearch中的內容不匹配。

您可以更改使用.DefaultFieldNameInferrer(Func<string, string>)ConnectionSettings

const string ESServer = "http://localhost:9200"; 
ConnectionSettings settings = new ConnectionSettings(new Uri(ESServer)) 
    .DefaultIndex("tiky"); 
    .MapDefaultTypeNames(map => map.Add(typeof(DAL.Faq), "faq")) 
    // pass POCO property names through verbatim 
    .DefaultFieldNameInferrer(s => s); 

ElasticClient client = new ElasticClient(settings); 
  • 由於搶在評論中提到的,a term query不分析 NEST如何序列化POCO屬性名稱查詢輸入。在針對在索引時分析的字段執行術語查詢時,爲了獲得匹配,您傳遞給術語查詢的查詢文本將需要將索引時應用的​​分析考慮在內。例如,

    • Question分析與the Standard Analyzer
    • "What's the Question?"Question值將被分析並索引作爲令牌"what's""the""question"
    • 一個術語的查詢將需要具有的"what's"查詢輸入, "the""question"爲匹配
  • 與詞條查詢不同,匹配查詢不會分析查詢輸入,因此搜索分析的輸出將用於查找匹配。結合1.中突出顯示的Pascal外殼,現在應該返回文檔。

    您還可以在Elasticsearch中擁有兩全其美的領域,即在索引時分析輸入以獲得全文搜索功能以及不經分析即可得到完全匹配的索引輸入。這與multi-fields完成,這裏要說的是指標Question性質既是分析創建一個映射的例子,而不是分析

    public class Faq 
    { 
        public string Question { get; set; } 
    } 
    
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); 
    var defaultIndex = "default-index"; 
    var connectionSettings = new ConnectionSettings(pool) 
         .DefaultIndex(defaultIndex) 
         .DefaultFieldNameInferrer(s => s); 
    
    var client = new ElasticClient(connectionSettings); 
    
    if (client.IndexExists(defaultIndex).Exists) 
        client.DeleteIndex(defaultIndex); 
    
    client.CreateIndex(defaultIndex, c => c 
        .Mappings(m => m 
         .Map<Faq>(mm => mm 
          // let NEST infer mapping from the POCO 
          .AutoMap() 
          // override any inferred mappings explicitly 
          .Properties(p => p 
           .String(s => s 
            .Name(n => n.Question) 
            .Fields(f => f 
             .String(ss => ss 
              .Name("raw") 
              .NotAnalyzed() 
             ) 
            ) 
           ) 
          ) 
         ) 
        ) 
    ); 
    

    這種情況的映射看起來像

    { 
        "mappings": { 
        "faq": { 
         "properties": { 
         "Question": { 
          "type": "string", 
          "fields": { 
          "raw": { 
           "type": "string", 
           "index": "not_analyzed" 
          } 
          } 
         } 
         } 
        } 
        } 
    } 
    

    下的"raw"子場"Question"字段將索引Question屬性的值,而不進行任何分析,即逐字。此子字段現在可用於查詢詞條查找完全匹配

    client.Search<Faq>(s => s 
        .Query(q => q 
         .Term(f => f.Question.Suffix("raw"), "What's the Question?") 
        ) 
    ); 
    

    找到與前面的示例相匹配的內容。

    +1

    感謝您的提示!這實際上是我需要的,並且很好的描述,謝謝! –