I would like to do a ElasticSearch query like this:
{
"query" :
{
"bool" :
{
"filter" : [
{
"terms" :
{
"name" : ["name1", "name2"]
}
},
{
"terms" :
{
"color" : ["orange", "red"]
}
}
]
}
}
}
I've tried to implement it in NEST like this:
_elasticClient
.SearchAsync<MyDocument>(s =>
s.Index("myindex")
.Query(q => q
.Bool(bq => bq
.Filter(fq =>
{
QueryContainer query = null;
if (nameList.Any()) {
query &= fq.Terms(t => t.Field(f => f.Name).Terms(nameList));
}
if (colorList.Any()) {
query &= fq.Terms(t => t.Field(f => f.Color).Terms(colorList));
}
return query;
})
)
)
);
But that gives me a query like this where the filters are wrapped inside a bool must:
{
"query" :
{
"bool" :
{
"filter" : [
{
"bool" :
{
"must" : [
{
"terms" :
{
"name" : ["name1", "name2"]
}
},
{
"terms" :
{
"color" : ["orange", "red"]
}
}
]
}
}
]
}
}
}
How should I change my NEST code to give me the right query? Do have have to add my terms to something other then a QueryContainer?
The
Filter
method of a bool query takes aparams Func<QueryContainerDescriptor<T>, QueryContainer>[]
so that you can pass it multiple expressions to represent multiple filterswhich results in
NEST also has the concept of conditionless queries, that is, if a query is determined to be conditionless, then it will not be serialized as part of the request.
What does it mean to be conditionless? Well, that depends on the query; for example, in the case of a
terms
query it is deemed to be conditionless if any of the following are truefield
doesn't have a valuenull
null
or empty stringsTo demonstrate
results in
Conditionless queries serve to make writing NEST queries easier in that you don't need to check if the collection has values before constructing a query. You can change conditionless semantics on a per query basis using
.Strict()
and.Verbatim()
.You can create a list of filters before you make a query if you want to check conditional filters as shown below:
If you don't need to check any condition before making filter query then you can have something like that: