在我的应用程序中,我将布尔参数传递给一个函数,该函数通过HasChildQuery
搜索弹性索引中的某些文档。
如果此布尔值设置为false,我想排除具有特定字段集的文档,当布尔值设置为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
为假。
但是对于这种情况的查询似乎是行不通的。
我希望&& (includeAutoLearnedData ? null : +new TermQuery
仅在布尔值为false时添加过滤器,并在查询为真时保持未修改
那么在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:
{}
答案 0 :(得分:1)
你所拥有的是正确的,你的方法是合理的,但你在输出中看到{}
的原因是因为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 中缺少关于无条件查询的部分。会添加一个!)