使用 NEST 的 Elasticsearch 查询不起作用

Elasticsearch query with NEST don't work

我正在使用 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();

DAL:

邮递员:

PS: 我跟着 this guide 创建了它

编辑:

索引映射:

我看到的一些内容可能对您有所帮助:

  1. 默认情况下,NEST camel 将 POCO 属性 名称序列化为请求中查询 JSON 的一部分,因此 x => x.Question 将序列化为 "question"。然而,查看您的映射,Elasticsearch 中的字段名称是 Pascal 大小写的,因此客户端所做的与 Elasticsearch 中的不匹配。

您可以通过在 ConnectionSettings

上使用 .DefaultFieldNameInferrer(Func<string, string>) 来更改 NEST 序列化 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);
  1. 正如 Rob 在评论中提到的,a term query 不分析 查询输入。当针对在索引时分析的字段执行术语查询时,为了获得匹配,您传递给术语查询的查询文本需要考虑在索引时应用的​​分析。例如,

    • Questionthe 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"
            }
          }
        }
      }
    }
  }
}

"Question" 字段下的 "raw" 子字段将索引 Question 属性 的值,无需任何分析,即逐字记录。此子字段现在可用于术语查询以查找完全匹配项

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

其中找到与上一个示例匹配的项。