asp.net - ASP.NET 中的弹性搜索 - 使用 & 符号
问题描述
我是 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 。
解决方案
默认情况下,对于文本字段,应用的分析器是标准分析器。此分析器应用标准标记器和小写标记过滤器。因此,当您针对该字段索引某个值时,标准分析器将应用于该值,并且生成的标记将针对该字段进行索引。
让我们通过例如对于字段companyName
(文本类型)来理解这一点,让我们假设传递的值是M&S Company Foo Bar
在索引文档时。应用标准分析器后该值的结果标记将是:
m
s
company
foo
bar
您会注意到,不仅空格,而且还&
用作分隔符来拆分和生成标记。
当您查询此字段并且未在搜索查询中传递任何分析器时,默认情况下,它也会应用相同的分析器进行搜索,该分析器也适用于对该字段的索引。因此,如果您搜索M&S
它会被标记为M
并S
因此实际搜索查询搜索这两个标记而不是M&S
.
要解决这个问题,您需要更改 field 的分析器companyName
。您可以创建一个自定义分析器,而不是标准分析器,它使用空格标记器和小写过滤器(使搜索不区分大小写)。为此,您需要更改设置和映射,如下所示:
{
"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
不会 &
忽略 ,。
推荐阅读
- gradle - 在 Gradle 中调试命令行调用
- python - AWS Lambda 在 prod 中部署时出现 400 错误
- c++ - RHEL 7 上的 gcc linux-64 编译器版本 8.4 - 未定义符号 clock_gettime@GLIBC_2.17
- javascript - 使用 Sheet.js 将 JSON 转换为 XLSX
- go - 解组任意结构的列表并将其附加到带有反射的切片
- jsf - FacesContext 将参数发送到新页面而不使用 url 并使用 faces-redirect = true?
- java - 打开二级缓存时Hazelcast node.js客户端错误
- python - 在 Marshmallow,Python [PUT] 请求中将值更改为 null
- android - 权限是否相关?
- excel - 导出的 .bas 模块有一个属性是什么意思?