【问题标题】:How can I use NEST QueryString and escape the special characters?如何使用 NEST QueryString 并转义特殊字符?
【发布时间】:2015-05-05 14:25:44
【问题描述】:

我在我的应用程序中使用 NEST 与 Elasticsearch 进行通信。

在这种情况下,用户输入他们的搜索词 F5503904902 会返回正确的结果。但是,如果他们搜索查询 F5503904902-90190F5503904902-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();
}

我希望得到任何帮助或指示为什么这不起作用或更好的方法来实现这一点。

【问题讨论】:

    标签: c# elasticsearch nest


    【解决方案1】:

    在 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 在幕后将该字段分成两部分。但是,因为我们将此字段设置为多字段,所以我们可以根据我们设置的“.raw”查询它。此查询将获得您正在寻找的结果。

    GET hilden1/type1/_search
    {
      "query": {
        "filtered": {
          "filter": {
            "term": {
              "multifield1.raw": "hello-dash"
            }
          }
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-23
      • 2012-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-11
      • 1970-01-01
      相关资源
      最近更新 更多