elasticsearch,nest,C#,Sql Server,Asp.net Mvc,elasticsearch,Nest" /> elasticsearch,nest,C#,Sql Server,Asp.net Mvc,elasticsearch,Nest" />

C# 使用NEST don'的Elasticsearch查询;行不通

C# 使用NEST don'的Elasticsearch查询;行不通,c#,sql-server,asp.net-mvc,elasticsearch,nest,C#,Sql Server,Asp.net Mvc,elasticsearch,Nest,我正在使用Microsoft SQL Server Management Studio和ElasticSearch 2.3.4以及ElasticSearch-jdbc-2.3.4.1,并将ES与我的mssql服务器链接。一切正常,但当我在MVC程序上使用NEST进行查询时,结果是空的。当我在search属性中放入一个空字符串时,我会得到元素,但当我尝试用一些过滤器填充它时,我会得到一个空结果。有人能帮我吗?提前谢谢 C#: const string ESServer = "http://loca

我正在使用Microsoft SQL Server Management Studio和ElasticSearch 2.3.4以及ElasticSearch-jdbc-2.3.4.1,并将ES与我的mssql服务器链接。一切正常,但当我在MVC程序上使用NEST进行查询时,结果是空的。当我在
search
属性中放入一个空字符串时,我会得到元素,但当我尝试用一些过滤器填充它时,我会得到一个空结果。有人能帮我吗?提前谢谢

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();
const string-ESServer=”http://localhost:9200";
ConnectionSettings设置=新的ConnectionSettings(新Uri(eServer));
设置。默认索引(“tiky”);
settings.MapDefaultTypeNames(map=>map.Add(typeof(DAL.Faq),“Faq”);
ElasticClient=新的ElasticClient(设置);
var response=client.Search(s=>s.Query(q=>q.Term(x=>x.Question,Search));
var result=response.Documents.ToList();
DAL:

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();
邮递员:

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();
PS:我跟着创建了它

编辑:


索引映射:

在这里,我可以看到一些有用的东西:

  • 默认情况下,在请求中将POCO属性名称序列化为查询JSON的一部分时,嵌套camel会将它们序列化为POCO属性名称,因此
    x=>x.Question
    将序列化为
    “Question”
    。但是,看看您的映射,Elasticsearch中的字段名是以Pascal大小写的,因此客户端所做的与Elasticsearch中的不匹配
  • 您可以使用
    ConnectionSettings上的
    defaultfieldnameinferer(Func)
    更改嵌套序列化POCO属性名称的方式

    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);
    
  • 正如Rob在评论中提到的,他不分析查询输入。当对在索引时分析的字段执行术语查询时,为了获得匹配项,传递给术语查询的查询文本需要考虑在索引时应用的分析。比如说,

    • 问题
    • “问题是什么?”
      问题值将作为标记
      “问题是什么”
      “问题”和
      “问题”
      进行分析和索引
    • 术语查询需要有
      “what's”
      “the”
      “question”
      的查询输入才能匹配
  • 与术语查询不同,匹配查询会分析查询输入,因此搜索分析的输出将用于查找匹配项。结合1中突出显示的Pascal case,您现在应该可以返回文档

    在Elasticsearch中,您还可以两全其美,即在索引时分析输入以实现全文搜索功能,以及在不进行分析的情况下分析索引输入以获得精确匹配。这是使用完成的,下面是创建映射的示例,该映射将
    问题
    属性索引为已分析和未分析的属性

    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()
                            )
                        )
                    )
                )
            )
        )
    );   
    
    “Question”
    字段下的
    “raw”
    子字段将索引
    Question
    属性的值,而无需进行任何分析,如逐字记录。现在可以在术语查询中使用此子字段来查找精确匹配项

    client.Search<Faq>(s => s
        .Query(q => q
            .Term(f => f.Question.Suffix("raw"), "What's the Question?")
        )
    );
    
    client.Search(s=>s
    .Query(q=>q
    .Term(f=>f.Question.Suffix(“原始”),“问题是什么?”)
    )
    );
    

    查找与上一个示例匹配的

    我可以看到以下几点可能会有所帮助:

  • 默认情况下,在请求中将POCO属性名称序列化为查询JSON的一部分时,嵌套camel会将它们序列化为POCO属性名称,因此
    x=>x.Question
    将序列化为
    “Question”
    。但是,看看您的映射,Elasticsearch中的字段名是以Pascal大小写的,因此客户端所做的与Elasticsearch中的不匹配
  • 您可以使用
    ConnectionSettings上的
    defaultfieldnameinferer(Func)
    更改嵌套序列化POCO属性名称的方式

    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);
    
  • 正如Rob在评论中提到的,他不分析查询输入。当对在索引时分析的字段执行术语查询时,为了获得匹配项,传递给术语查询的查询文本需要考虑在索引时应用的分析。比如说,

    • 问题
    • “问题是什么?”
      问题值将作为标记
      “问题是什么”
      “问题”和
      “问题”
      进行分析和索引
    • 术语查询需要有
      “what's”
      “the”
      “question”
      的查询输入才能匹配
  • 与术语查询不同,匹配查询会分析查询输入,因此搜索分析的输出将用于查找匹配项。结合1中突出显示的Pascal case,您现在应该可以返回文档

    在Elasticsearch中,您还可以两全其美,即在索引时分析输入以实现全文搜索功能,以及在不进行分析的情况下分析索引输入以获得精确匹配。这是使用完成的,下面是创建映射的示例,该映射将
    问题
    属性索引为已分析和未分析的属性

    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()
                            )
                        )
                    )
                )
            )
        )
    );   
    
    “Question”
    字段下的
    “raw”
    子字段将索引
    Question
    属性的值,而无需进行任何分析,如逐字记录。现在可以在术语查询中使用此子字段来查找精确匹配项

    client.Search<Faq>(s => s
        .Query(q => q
            .Term(f => f.Question.Suffix("raw"), "What's the Question?")
        )
    );
    
    client.Search(s=>s
    .Query(q=>q
    .Term(f=>f.Question.Suffix(“原始”),“问题是什么?”)
    )
    );
    

    查找与上一个示例匹配的

    你可以分享索引映射吗<代码>http://localhost:9200/tiky/_mapping
    @Rob-Sure,我已经更新了问题
    问题
    字段已分析,
    术语查询
    可用于
    未分析的
    字段。你可以多读一些,哦,是的,我明白了。所以,如果我想得到包含值的元素