【问题标题】:Why escaping backslashes are appear in ElasticSearch Nest Query?为什么 ElasticSearch Nest Query 中会出现转义反斜杠?
【发布时间】:2020-12-07 11:43:37
【问题描述】:

我正在尝试编写一个 C# 方法来获取控制器的 queryString 并将其转换为 ElasticSearch 查询,如下所示:

public QueryContainerDescriptor<T> Convert<T> (IQueryCollection query) where T: class
{
    var selector = new QueryContainerDescriptor<T>();
    List<QueryContainer> Must = new List<QueryContainer>();
    foreach(var key in query.keys)
    {
        string value = query[key];
        var match = new MatchQuery { Field = $"{key}.keyword", Query = value };
        list.Add(match)
    }
    selector.Bool(q => q.Must(Must.ToArray()));
    return selector;
}

它按预期工作,但如果我传递带有反斜杠的 queryString 值,例如:

http://localhost:5000/api/indexData?user=ESKA\\USER

应该转换成这个查询:

{ "bool": { "must": [ { "match" : { "user.keyword": "ESKA\\USER" } } ] }

ElasticSearch 将不会返回任何内容,因为查询的值将是:ESKA\\\\USER,带有 4 个反斜杠,例如:

{ "bool": { "must": [ { "match" : { "user.keyword": "ESKA\\\\USER" } } ] }

我该如何解决这个问题?

【问题讨论】:

    标签: c# .net string elasticsearch nest


    【解决方案1】:

    我不认为 N​​est 正在执行任何反斜杠转义。这是一个写出请求(和响应,如果使用发送请求的IConnection)的示例

    private static void Main()
    {
        var pool = new SingleNodeConnectionPool(new Uri($"http://localhost:9200"));
        var settings = new ConnectionSettings(pool, new InMemoryConnection())
            .DefaultIndex("default_index")
            .DisableDirectStreaming()
            .PrettyJson()
            .OnRequestCompleted(callDetails =>
            {
                if (callDetails.RequestBodyInBytes != null)
                {
                    var json = JObject.Parse(Encoding.UTF8.GetString(callDetails.RequestBodyInBytes));
        
                    Console.WriteLine(
                        $"{callDetails.HttpMethod} {callDetails.Uri} \n" +
                        $"{json.ToString(Newtonsoft.Json.Formatting.Indented)}");
                }
                else
                {
                    Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
                }
        
                Console.WriteLine();
        
                if (callDetails.ResponseBodyInBytes != null)
                {
                    Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
                             $"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" +
                             $"{new string('-', 30)}\n");
                }
                else
                {
                    Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
                             $"{new string('-', 30)}\n");
                }
            });
            
        var client = new ElasticClient(settings);
        
        var collection = new QueryCollection(new Dictionary<string, StringValues>
        {
            { "user", "ESKA\\USER" }
        });
        
        var response = client.Search<object>(s => s
            .Query(q => Convert<object>(q, collection))
        );
    }
    
    public static QueryContainerDescriptor<T> Convert<T>(QueryContainerDescriptor<T> selector, IQueryCollection query) where T : class
    {
        List<QueryContainer> Must = new List<QueryContainer>();
        foreach (var key in query.Keys)
        {
            string value = query[key];
            var match = new MatchQuery { Field = $"{key}.keyword", Query = value };
            Must.Add(match);
        }
        selector.Bool(q => q.Must(Must.ToArray()));
        return selector;
    }
    

    结果查询是

    POST http://localhost:9200/default_index/_search?pretty=true&typed_keys=true 
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "user.keyword": {
                  "query": "ESKA\\USER"
                }
              }
            }
          ]
        }
      }
    }
    

    如果user 的值是verbatim string literal @"ESKA\\USER",那么生成的查询将是

    "user.keyword": {
        "query": "ESKA\\\\USER"
    }
    

    因为逐字字符串文字中的每个\ 都需要转义。

    【讨论】:

      猜你喜欢
      • 2021-11-16
      • 1970-01-01
      • 2022-01-17
      相关资源
      最近更新 更多