我正在使用NEST与我的应用程序中的Elasticsearch通信。
在这种情况下,用户输入F5503904902返回正确结果的搜索词。但是,如果他们搜索查询F5503904902-90190或F5503904902-90190_55F结果不回来。
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(); }
我很乐意提供任何帮助或指示,以了解为什么这不起作用或实现此目的的更好方法。
在ElasticSearch中,破折号和下划线不是特殊字符,但它们是导致术语分离的字符。重要的是现场索引。我建议设置一个多字段。
https://www.elastic.co/guide/zh-CN/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会将字段分为幕后两部分。但是,因为我们将此字段设置为多字段,所以我们可以根据设置的“ .raw”查询它。该查询将获得您想要的结果。
GET hilden1/type1/_search { "query": { "filtered": { "filter": { "term": { "multifield1.raw": "hello-dash" } } } } }