C# 使用NEST don'的Elasticsearch查询;行不通
我正在使用Microsoft SQL Server Management Studio和ElasticSearch 2.3.4以及ElasticSearch-jdbc-2.3.4.1,并将ES与我的mssql服务器链接。一切正常,但当我在MVC程序上使用NEST进行查询时,结果是空的。当我在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
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:我跟着创建了它
编辑:
索引映射:在这里,我可以看到一些有用的东西:
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,我已经更新了问题问题
字段已分析,术语查询
可用于未分析的
字段。你可以多读一些,哦,是的,我明白了。所以,如果我想得到包含值的元素