在我的应用程序中,我将 bool(boolean) 参数传递给一个函数,该函数通过HasChildQuery
在我的 flex 索引中搜索某些文档。
如果此 bool(boolean) 值设置为false,则我想排除具有特定字段集的文档,当 bool(boolean) 值设置为true时,我不希望出现第二种情况。
到目前为止,这是我的方法:
Query = new HasChildQuery
{
// ...
Query = new CommonTermsQuery
{
// This Query always needs to be there
Field = Nest.Infer.Field<FaqQuestion>(q => q.Content),
Query = content
}
&& (includeAutoLearnedData ? null : +new TermQuery
{
// I only want this Query if includeAutoLearnedData is false
Field = Nest.Infer.Field<FaqQuestion>(q => q.AutoLearned),
Value = false
})
}
我的想法是始终生成这样的请求
has_child
|
|__ ...
|
|__ common_terms
并扩展到
has_child
|
|__ ...
|
|__ bool
|
|__must
| |
| |__common_terms
|
|__filter
|
|__term
如果
includeAutoLearnedData
为false。但是查询为真的情况似乎不起作用。
我希望
&& (includeAutoLearnedData ? null : +new TermQuery
仅在boolean为false时才添加过滤器,而在true时不修改查询那么在NEST中的特定条件下包括附加过滤器查询的正确方法是什么?
编辑:
当我从ElasticClient获得结果并希望它具有类似以下内容时,我设置了一个断点
Valid NEST response built from a successful low level call on POST: /faq/_search
# Audit trail of this API call:
- [1] HealthyResponse: Node: http://localhost:9200/ Took: 00:00:00.0770000
# Request:
{
"query": {
"has_child": {
"bool": {
"must": [{
"common_terms": { ... }
}],
"filter": [{
"term": { ... }
}]
}
}
}
}
但实际结果有:
# Request:
{}
最佳答案
您所拥有的是正确的,并且您的方法是正确的,但是在输出中看到{}
的原因是由于NEST中的无条件查询;本质上,如果查询未设置某些属性(或者为它们分配了null
或空字符串),则该查询被视为无条件的,并且不会作为请求的一部分进行序列化。例如,对于term
查询,如果
field
分配了一个空字符串,或者是null
字符串,表达式或属性value
是null
或空字符串则
term
查询被认为是无条件的。您可以使用 verbatim
and strict
更改此行为Verbatim
可以将单个查询标记为逐字查询,这意味着即使无条件查询也应像一样发送给Elasticsearch 。
Strict
可以将各个查询标记为严格的含义,即如果它们是无条件的,则会引发异常。当查询必须具有输入值时,这很有用。
证明您的方法有效
void Main()
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var defaultIndex = "default-index";
var connectionSettings = new ConnectionSettings(pool, new InMemoryConnection())
.DefaultIndex(defaultIndex)
.PrettyJson()
.DisableDirectStreaming()
.OnRequestCompleted(response =>
{
if (response.RequestBodyInBytes != null)
{
Console.WriteLine(
$"{response.HttpMethod} {response.Uri} \n" +
$"{Encoding.UTF8.GetString(response.RequestBodyInBytes)}");
}
else
{
Console.WriteLine($"{response.HttpMethod} {response.Uri}");
}
Console.WriteLine();
if (response.ResponseBodyInBytes != null)
{
Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
$"{Encoding.UTF8.GetString(response.ResponseBodyInBytes)}\n" +
$"{new string('-', 30)}\n");
}
else
{
Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
$"{new string('-', 30)}\n");
}
});
var client = new ElasticClient(connectionSettings);
var includeAutoLearnedData = false;
var request = new SearchRequest<Message>
{
Query = new HasChildQuery
{
Type = "child",
Query = new CommonTermsQuery
{
Field = Infer.Field<Message>(m => m.Content),
Query = "commonterms"
}
&& (includeAutoLearnedData ? null : +new TermQuery
{
Field = Infer.Field<Message>(m => m.Content),
Value = "term"
})
}
};
client.Search<Message>(request);
}
public class Message
{
public string Content { get; set; }
}
当
includeAutoLearnedData
为false
时产生以下查询{
"query": {
"has_child": {
"type": "child",
"query": {
"bool": {
"must": [
{
"common": {
"content": {
"query": "commonterms"
}
}
}
],
"filter": [
{
"term": {
"content": {
"value": "term"
}
}
}
]
}
}
}
}
}
当它是
true
{
"query": {
"has_child": {
"type": "child",
"query": {
"common": {
"content": {
"query": "commonterms"
}
}
}
}
}
}
(我注意到我们在 latest documentation 中缺少关于无条件查询的部分。将添加一个!)
关于c# - NEST:在条件下添加术语查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44651876/