我是ASP.NET中的Elastic Search的新手,到目前为止,我有一个问题无法解决。
从文档中,我已经看到&
符号没有作为特殊字符列出。但是,当我提交搜索与符号时,它会被完全忽略。例如,如果我搜索procter & gamble
,则&
符号将被完全忽略。这给我带来了很多问题,因为我有一些公司的名字像M&S
。当&
符号被忽略时,我基本上得到了所有带有M或S的东西。如果我尝试使用精确搜索(M&S
),则会遇到相同的问题。
我的代码是:
void Connect()
{
node = new Uri(ConfigurationManager.AppSettings["Url"]);
settings = new ConnectionSettings(node);
settings.DefaultIndex(ConfigurationManager.AppSettings["defaultIndex"]);
settings.ThrowExceptions(true);
client = new ElasticClient(settings);
}
private string escapeChars(string inStr) {
var temp = inStr;
temp = temp
.Replace(@"\", @"\\")
.Replace(@">",string.Empty)
.Replace(@"<",string.Empty)
.Replace(@"{",string.Empty)
.Replace(@"}",string.Empty)
.Replace(@"[",string.Empty)
.Replace(@"]",string.Empty)
.Replace(@"*",string.Empty)
.Replace(@"?",string.Empty)
.Replace(@":",string.Empty)
.Replace(@"/",string.Empty);
return temp;
}
然后进入我的功能之一
Connect();
ISearchResponse<ElasticSearch_Result> search_result;
var QString = escapeChars(searchString);
search_result = client.Search<ElasticSearch_Result>(s => s
.From(0)
.Size(101)
.Query(q =>
q.QueryString(b =>
b.Query(QString)
//.Analyzer("whitespace")
.Fields(fs => fs.Field(f => f.CompanyName))
)
)
.Highlight(h => h
.Order("score")
.TagsSchema("styled")
.Fields(fs => fs
.Field(f => f.CompanyName)
)
)
);
我尝试过包括分析器,但是后来我发现它们改变了分词器split
单词的方式。我无法对令牌生成器进行更改。
我希望能够有以下情形:
搜索:M&S Company Foo Bar
代币:M&S
Company
Foo
Bar
+如果有可能也拥有M
S
个代币,则加分
我正在使用弹性搜索V5.0。
任何帮助都非常欢迎。包含比https://www.elastic.co/guide/en/elasticsearch/client/net-api/5.x/writing-queries.html更好的文档。
答案 0 :(得分:2)
默认情况下,分析器应用的文本字段为standard analyzer。该分析器将standard tokenizer与lowercase token filter一起使用。因此,当您根据该字段为某个值编制索引时,标准分析器将应用于该值,并且由此产生的令牌也将针对该字段编制索引。
让我们通过例如对于字段companyName
(文本类型),我们假设索引文档时传递的值为M&S Company Foo Bar
。应用标准分析仪后,该值的结果标记为:
m
s
company
foo
bar
您会注意到,不仅空格,而且&
都被用作分隔符,用于分割和生成令牌。
当您对此字段进行查询并且未在搜索查询中传递任何分析器时,默认情况下,它也会应用同一分析器进行搜索,该分析器也将用于对该字段建立索引。因此,如果您搜索M&S
,它将被标记为M
和S
,因此实际的搜索查询将搜索这两个标记而不是M&S
。
要解决此问题,您需要更改字段companyName
的分析器。可以使用whitespace tokenizer和小写过滤器来创建自定义分析器,而不是标准分析器(以使搜索不区分大小写)。为此,您需要如下更改设置和映射:
{
"settings": {
"analysis": {
"analyzer": {
"whitespace_lowercase": {
"tokenizer": "whitespace",
"filter": [
"lowercase"
]
}
}
}
},
"mappings": {
"_doc": {
"properties": {
"companyName": {
"type": "text",
"analyzer": "whitespace_lowercase",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
}
现在对于上述输入,生成的令牌将为:
m&s
company
foo
bar
这将确保在搜索M&S
时不会忽略&
。