2017-03-02 139 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

    感谢您的提示!这实际上是我需要的,并且很好的描述,谢谢! –