我正在使用NEST在我的应用程序中与Elasticsearch进行通信。
在这种情况下,用户输入搜索词F5503904902
,返回正确的结果。但是,如果他们搜索查询F5503904902-90190
或F5503904902-90190_55F
,结果就不会回来。
我认为这是因为特殊字符,所以我试图逃避它们 - 但是后来也没有结果。我的查询是否正确,我做错了吗? 另外我在转义的查询的末尾附加一个通配符,以匹配任何开放的结尾。
搜索方法:
public IPagedSearchResult<MyFileObject> Find(ISearchQuery query)
{
ElasticClient client = ElasticClientManager.GetClient(_indexCluster, ElasticSearchIndexName.MyFileObjects);
string queryString = EscapeSearchQuery(query.Query) + "*";
var searchResults = client.Search<MyFileObject>(s => s
.From(query.Skip)
.Size(query.Take)
.QueryString(queryString));
IPagedSearchResult<MyFileObject> pagedSearchResult = new PagedSearchResult<MyFileObject>();
pagedSearchResult.Results = searchResults.Documents;
pagedSearchResult.Skip = query.Skip;
pagedSearchResult.Take = query.Take;
pagedSearchResult.Total = Convert.ToInt32(searchResults.Total);
return pagedSearchResult;
}
逃脱方法:
private string EscapeSearchQuery(string query)
{
if (String.IsNullOrWhiteSpace(query)) return query;
//&& || not handled here
char[] special = { '+', '-', '=', '>', '<', '!', '(', ')', '{', '}', '[', ']', '^', '\"', '~', '*', '?', ':', '\\', '/', ' ' };
char[] qArray = query.ToCharArray();
StringBuilder sb = new StringBuilder();
foreach (var chr in qArray)
{
if (special.Contains(chr))
{
sb.Append(String.Format("\\{0}", chr));
}
else
{
sb.Append(chr);
}
}
return sb.ToString();
}
我会喜欢任何帮助或指示为什么这不是工作或更好的方法来实现这一目标。
答案 0 :(得分:3)
在ElasticSearch中,短划线和下划线不是特殊字符,但它们是导致术语被拆分的字符。重要的是该领域的指数。我建议设置一个多字段。
https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/multi-fields.html
以下是一个例子:
PUT hilden1
PUT hilden1/type1/_mapping
{
"properties": {
"multifield1": {
"type": "string",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
POST hilden1/type1
{
"multifield1": "hello"
}
POST hilden1/type1
{
"multifield1": "hello_underscore"
}
POST hilden1/type1
{
"multifield1": "hello-dash"
}
让我们尝试找到虚线值:
GET hilden1/type1/_search
{
"query": {
"filtered": {
"filter": {
"term": {
"multifield1": "hello-dash"
}
}
}
}
}
返回没有结果,因为ES正在将场分割为幕后的两部分。但是,因为我们将此字段设置为多字段,我们可以根据&#34; .raw&#34;来查询它。我们设定的。此查询将获得您正在寻找的结果。
GET hilden1/type1/_search
{
"query": {
"filtered": {
"filter": {
"term": {
"multifield1.raw": "hello-dash"
}
}
}
}
}