我正在使用Elastic Search开发.NET应用程序。我使用ES River来索引数据。 结果(在Sense中)看起来有点像这样:
{
"_index": "musicstore",
"_type": "songs",
"_id": "J2k-NjXjRa-mgWKAq0RMlw",
"_score": 1,
"_source": {
"songID": 42,
"tempo": "andante",
"metrum": "3/4 E8",
"intonation": "F",
"title": "Song",
"archiveSongNumber": "3684",
"Year": 2000,
"Place": "London"
}
},
要访问索引数据,我使用与此类似的NEST查询:
var result = ElasticClient.Search<Song>(s => s.Query(q => q.Term(p => p.title, "Song")));
当我搜索某个字段时,我遇到的问题是查询没有返回任何结果。 例如,当我搜索标题,songID,tempo或archiveSongNumber时,查询工作正常,它返回与Sense相同的结果,但是当我搜索Year,Place,metrum等时,查询不会返回任何结果,但是应该(Sense确实应该)。 像这样的查询工作(并返回正确的结果):
var result = ElasticClient.Search<Song>(s => s.Query(q => q.Term(p => p.title, "Song")));
var result = ElasticClient.Search<Song>(s => s.Query(q => q.Term(p => p.songID, 42)));
var result = ElasticClient.Search<Song>(s => s.Query(q => q.Term(p => p.archiveSongNumber , "3684")));
这样的查询不会返回任何结果(但它们应该):
var result = ElasticClient.Search<Song>(s => s.Query(q => q.Term(p => p.Place, "London")));
var result = ElasticClient.Search<Song>(s => s.Query(q => q.Term(p => p.Year, 2000)));
我做错了什么?我在索引数据时是不是搞砸了?
更新 映射看起来像这样:
{
"musicstore": {
"mappings": {
"songs": {
"properties": {
"Year": {
"type": "long"
},
"Place": {
"type": "string"
},
"archiveSongNumber": {
"type": "string"
},
"songID": {
"type": "long"
},
"intonation": {
"type": "string"
},
"metrum": {
"type": "string"
},
"title": {
"type": "string"
},
"tempo": {
"type": "string"
}
}
}
}
}
}
更新2:
ES河流请求如下所示:
PUT /_river/songs_river/_meta
{
"type":"jdbc",
"jdbc": {
"driver":"com.microsoft.sqlserver.jdbc.SQLServerDriver",
"url":"jdbc:sqlserver://ip_address:1433;databaseName=database",
"user":"user",
"password":"password",
"strategy":"simple",
"poll":"300s",
"autocommit":true,
"fetchsize":10,
"max_retries":3,
"max_retries_wait":"10s",
"index":"musicstore",
"type":"songs",
"analysis": {
"analyzer" :{
"whitespace" :{
"type" : "whitespace",
"filter":"lowercase"
}
}
},
"sql":"some_sql_query"
}
}
ES客户端配置如下所示:
private static ElasticClient ElasticClient
{
get
{
Uri localhost = new Uri("http://localhost:9200");
var setting = new ConnectionSettings(localhost);
setting.SetDefaultIndex("musicstore").MapDefaultTypeNames(d => d.Add(typeof(Song), "songs"));
setting.SetConnectionStatusHandler(c =>
{
if (!c.Success)
throw new Exception(c.ToString());
});
return new ElasticClient(setting);
}
}
答案 0 :(得分:2)
通过查看您的映射,此处的问题很可能是您的所有字段在编制索引时都是analyzed
,但您正在使用term queries
与NEST,not analyzed
,意思是他们只能找到完全匹配。如果您未在映射中明确指定分析器,则Elasticsearch默认为standard analyzer。
当您使用查询字符串在Elasticsearch中执行搜索时,就像您在Sense中所做的那样:GET _search/?q=Place:London
,query string query是由Elasticsearch运行的,这是不同于term query。
从您的示例来看,您实际上看起来并没有使用query string syntax。您可能需要match query代替:
client.Search<Song>(s => s
.Query(q => q
.Match(m => m
.OnField(p => p.Place)
.Query("London")
)
)
);
如果您确实想要使用感知执行的query string query
,那么您可以使用QueryString
:
client.Search<Song>(s => s
.Query(q => q
.QueryString(qs => qs
.OnFields(p => p.Place)
.Query("London")
)
)
);
希望有所帮助。我建议您查看getting started guide,特别是exact values vs. full text上的部分。
答案 1 :(得分:0)
在您的字词字段中添加“关键字”后缀:
var result = ElasticClient.Search<Song>(s => s
.Query(q => q
.Term(p => p
.Field(x => x.Year.Suffix("keyword")).Value(2000))));
尝试一下,它将起作用!