为啥 ElasticSearch Nest Query 中会出现转义反斜杠?
Posted
技术标签:
【中文标题】为啥 ElasticSearch Nest Query 中会出现转义反斜杠?【英文标题】: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" ]
我该如何解决这个问题?
【问题讨论】:
【参考方案1】:我不认为 Nest 正在执行任何反斜杠转义。这是一个写出请求(和响应,如果使用发送请求的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"
因为逐字字符串文字中的每个\
都需要转义。
【讨论】:
以上是关于为啥 ElasticSearch Nest Query 中会出现转义反斜杠?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 ElasticSearch Nest 客户端会为 MultiPolygonGeoShape 抛出 invalid_shape_exception