首页 > 解决方案 > 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 。

标签: asp.netasp.net-mvcelasticsearchtokenize

解决方案


默认情况下,对于文本字段,应用的分析器是标准分析器。此分析器应用标准标记器和小写标记过滤器。因此,当您针对该字段索引某个值时,标准分析器将应用于该值,并且生成的标记将针对该字段进行索引。

让我们通过例如对于字段companyName(文本类型)来理解这一点,让我们假设传递的值是M&S Company Foo Bar在索引文档时。应用标准分析器后该值的结果标记将是:

m
s
company
foo
bar

您会注意到,不仅空格,而且还&用作分隔符来拆分和生成标记。

当您查询此字段并且未在搜索查询中传递任何分析器时,默认情况下,它也会应用相同的分析器进行搜索,该分析器也适用于对该字段的索引。因此,如果您搜索M&S它会被标记为MS因此实际搜索查询搜索这两个标记而不是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不会 &忽略 ,。


推荐阅读