弹性搜索:查询字符串和数字并不总是返回想要的结果
Elastic Search: Query string and number not always returning wanted result
我们有弹性搜索 5.5 设置。我们使用 nest 通过 C# 执行我们的查询。
执行以下查询时:
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "00917751"
}
}
]
}
}
}
我们得到了想要的结果:一个以数字作为标识符的结果。
执行查询时:
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "917751"
}
}
]
}
}
}
我们没有得到任何结果。
我们正在搜索的值在字段 searchIndentifier 中,值为“1-00917751”。
我们有一个名为 "final"
的自定义分析器
.Custom("final", cu => cu
.Tokenizer("keyword").Filters(new List() { "lowercase" }))
字段 searchIndentifier 没有设置自定义分析器。我尝试在其中添加空白分词器,但没有任何区别。
当我尝试使用查询 "S328" 搜索值 "S328-25" 时,另一个名为 "searchObjectNo" 的字段确实有效。这些字段完全相同。
有什么想法吗?
另一个相关问题:
执行查询时
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "1-00917751"
}
}
]
}
}
}
我们得到了很多结果。我希望 return 只有 1 个结果。我们将如何做到这一点?
谢谢
学步
设置和映射:https://jsonblob.com/9dbf33f6-cd3e-11e8-8f17-c9de91b6f9d1
searchIndentifier
字段映射为 text
数据类型,默认情况下将进行分析并使用标准分析器。使用 Analyze API,您可以看到哪些术语将存储在 1-00917751
的倒排索引中
var client = new ElasticClient();
var analyzeResponse = client.Analyze(a => a
.Text("1-00917751")
);
哪个returns
{
"tokens" : [
{
"token" : "1",
"start_offset" : 0,
"end_offset" : 1,
"type" : "<NUM>",
"position" : 0
},
{
"token" : "00917751",
"start_offset" : 2,
"end_offset" : 10,
"type" : "<NUM>",
"position" : 1
}
]
}
您将获得 query_string
查询与查询输入 00917751
的匹配项,因为这与存储在倒排索引中的术语之一匹配,这是索引时分析的结果输入 1-00917751
.
您不会获得 917751
的匹配项,因为倒排索引中没有匹配项。您可以定义一个分析链,从数字中删除前导零并保留原始标记,例如
private static void Main()
{
var defaultIndex = "foobarbaz";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);
var client = new ElasticClient(settings);
client.CreateIndex(defaultIndex, c => c
.Settings(s => s
.Analysis(a => a
.Analyzers(an => an
.Custom("trim_leading_zero", ca => ca
.Tokenizer("standard")
.Filters(
"standard",
"lowercase",
"trim_leading_zero",
"trim_zero_length")
)
)
.TokenFilters(tf => tf
.PatternReplace("trim_leading_zero", pr => pr
.Pattern("^0+(.*)")
.Replacement("")
)
.Length("trim_zero_length", t => t
.Min(1)
)
)
)
)
.Mappings(m => m
.Map<MyDocument>(mm => mm
.AutoMap()
.Properties(p => p
.Text(t => t
.Name(n => n.SearchIndentifier)
.Analyzer("trim_leading_zero")
.Fields(f => f
.Keyword(k => k
.Name("keyword")
.IgnoreAbove(256)
)
)
)
)
)
)
);
client.Index(new MyDocument { SearchIndentifier = "1-00917751" }, i => i
.Refresh(Refresh.WaitFor)
);
client.Search<MyDocument>(s => s
.Query(q => q
.QueryString(qs => qs
.Query("917751")
)
)
);
}
public class MyDocument
{
public string SearchIndentifier { get; set; }
}
pattern_replacement
标记过滤器将从标记中 trim 前导零。
搜索查询returns索引文档
{
"took" : 69,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.33310556,
"hits" : [
{
"_index" : "foobarbaz",
"_type" : "mydocument",
"_id" : "MVF4bmYBJZHQAT-BUx1K",
"_score" : 0.33310556,
"_source" : {
"searchIndentifier" : "1-00917751"
}
}
]
}
}
我们有弹性搜索 5.5 设置。我们使用 nest 通过 C# 执行我们的查询。
执行以下查询时:
{ "query": { "bool": { "must": [ { "query_string": { "query": "00917751" } } ] } } }
我们得到了想要的结果:一个以数字作为标识符的结果。
执行查询时:
{ "query": { "bool": { "must": [ { "query_string": { "query": "917751" } } ] } } }
我们没有得到任何结果。
我们正在搜索的值在字段 searchIndentifier 中,值为“1-00917751”。
我们有一个名为 "final"
的自定义分析器.Custom("final", cu => cu .Tokenizer("keyword").Filters(new List() { "lowercase" }))
字段 searchIndentifier 没有设置自定义分析器。我尝试在其中添加空白分词器,但没有任何区别。
当我尝试使用查询 "S328" 搜索值 "S328-25" 时,另一个名为 "searchObjectNo" 的字段确实有效。这些字段完全相同。
有什么想法吗?
另一个相关问题: 执行查询时
{ "query": { "bool": { "must": [ { "query_string": { "query": "1-00917751" } } ] } } }
我们得到了很多结果。我希望 return 只有 1 个结果。我们将如何做到这一点?
谢谢 学步
设置和映射:https://jsonblob.com/9dbf33f6-cd3e-11e8-8f17-c9de91b6f9d1
searchIndentifier
字段映射为 text
数据类型,默认情况下将进行分析并使用标准分析器。使用 Analyze API,您可以看到哪些术语将存储在 1-00917751
var client = new ElasticClient();
var analyzeResponse = client.Analyze(a => a
.Text("1-00917751")
);
哪个returns
{
"tokens" : [
{
"token" : "1",
"start_offset" : 0,
"end_offset" : 1,
"type" : "<NUM>",
"position" : 0
},
{
"token" : "00917751",
"start_offset" : 2,
"end_offset" : 10,
"type" : "<NUM>",
"position" : 1
}
]
}
您将获得 query_string
查询与查询输入 00917751
的匹配项,因为这与存储在倒排索引中的术语之一匹配,这是索引时分析的结果输入 1-00917751
.
您不会获得 917751
的匹配项,因为倒排索引中没有匹配项。您可以定义一个分析链,从数字中删除前导零并保留原始标记,例如
private static void Main()
{
var defaultIndex = "foobarbaz";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);
var client = new ElasticClient(settings);
client.CreateIndex(defaultIndex, c => c
.Settings(s => s
.Analysis(a => a
.Analyzers(an => an
.Custom("trim_leading_zero", ca => ca
.Tokenizer("standard")
.Filters(
"standard",
"lowercase",
"trim_leading_zero",
"trim_zero_length")
)
)
.TokenFilters(tf => tf
.PatternReplace("trim_leading_zero", pr => pr
.Pattern("^0+(.*)")
.Replacement("")
)
.Length("trim_zero_length", t => t
.Min(1)
)
)
)
)
.Mappings(m => m
.Map<MyDocument>(mm => mm
.AutoMap()
.Properties(p => p
.Text(t => t
.Name(n => n.SearchIndentifier)
.Analyzer("trim_leading_zero")
.Fields(f => f
.Keyword(k => k
.Name("keyword")
.IgnoreAbove(256)
)
)
)
)
)
)
);
client.Index(new MyDocument { SearchIndentifier = "1-00917751" }, i => i
.Refresh(Refresh.WaitFor)
);
client.Search<MyDocument>(s => s
.Query(q => q
.QueryString(qs => qs
.Query("917751")
)
)
);
}
public class MyDocument
{
public string SearchIndentifier { get; set; }
}
pattern_replacement
标记过滤器将从标记中 trim 前导零。
搜索查询returns索引文档
{
"took" : 69,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.33310556,
"hits" : [
{
"_index" : "foobarbaz",
"_type" : "mydocument",
"_id" : "MVF4bmYBJZHQAT-BUx1K",
"_score" : 0.33310556,
"_source" : {
"searchIndentifier" : "1-00917751"
}
}
]
}
}