c# - 为什么 ElasticSearch Nest Query 中会出现转义反斜杠?
问题描述
我正在尝试编写一个获取queryString
控制器并将其转换为ElasticSearch查询的 C# 方法,如下所示:
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" } } ] }
我该如何解决这个问题?
解决方案
我不认为 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
值是逐字字符串文字 @"ESKA\\USER"
,那么结果查询将是
"user.keyword": {
"query": "ESKA\\\\USER"
}
因为\
逐字字符串文字中的每个都需要转义。
推荐阅读
- python - 将掩码应用于张量时 Lambda 层中的 NoneType 错误
- ubuntu - 远程桌面连接到 GCP 中的 Ubuntu
- django - 如何为一个模板实现多个表单
- python - C++ 和 Python:将二维双指针数组从 python 传递并返回到 C++
- excel - 在 Excel 中突出显示特定列中的负值
- python - 当依赖项不可用时测试代码
- c# - 将大文件上传到 API 并将其存储到 blob
- typescript - TS2322 X 型 | 是 | Z[] 不可分配给类型 Z[]- Typescript
- docker - 使用 HTTP 503 的 Docker 群负载平衡
- amazon-dynamodb - DynamoDB REMOVE 事件仅返回 HASH 和 RANGE 值,而不是所有键