-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
NEST/Elasticsearch.Net version:
NEST 2.4.4
Elasticsearch.Net.2.4.4
Elasticsearch version:
2.4.0
Description of the problem including expected versus actual behavior:
When functionally generating queries that includes a dynamic field's child multi-field, the first query condition is generated properly, but subsequent conditions will continue to use the original field name instead of the correct field name. Only occurs when there both a constant and a non-constant in the Field() function's expression.
Steps to reproduce:
using System;
using System.Collections.Generic;
using Nest;
using System.Text;
namespace Test
{
public class Program
{
public static void Main()
{
var connectionSettings = new ConnectionSettings(new Uri("http://localhost:9200"));
connectionSettings.DisableDirectStreaming();
connectionSettings.PrettyJson();
var elasticClient = new ElasticClient(connectionSettings);
var expected = elasticClient.Search<TestDocument>(sd => sd
.Query(qcd => qcd
.Bool(bqd => bqd
.Must(
qcd
.Term(tqd => tqd
.Field(td => td.fields["foo"].Suffix("suffix"))
.Value("a")),
qcd
.Term(tqd => tqd
.Field(td => td.fields["bar"].Suffix("suffix"))
.Value("b"))
)
)
)
);
var actual = elasticClient.Search<TestDocument>(sd => sd
.Query(qcd => qcd
.Bool(bqd => bqd
.Must(
CreateCondition("foo", "a"),
CreateCondition("bar", "b")
)
)
)
);
Console.WriteLine("Expected: {0}", Encoding.UTF8.GetString(expected.ApiCall.RequestBodyInBytes));
Console.WriteLine();
Console.WriteLine("Actual: {0}", Encoding.UTF8.GetString(actual.ApiCall.RequestBodyInBytes));
}
private static Func<QueryContainerDescriptor<TestDocument>, QueryContainer> CreateCondition(string fieldName, string value)
{
return qcd => qcd
.Term(tqd => tqd
.Field(td => td.fields[fieldName].Suffix("suffix"))
.Value(value));
}
private class TestDocument
{
public IDictionary<string, string> fields { get; set; }
}
}
}Outputs:
Expected: {
"query": {
"bool": {
"must": [
{
"term": {
"fields.foo.suffix": {
"value": "a"
}
}
},
{
"term": {
"fields.bar.suffix": {
"value": "b"
}
}
}
]
}
}
}
Actual: {
"query": {
"bool": {
"must": [
{
"term": {
"fields.foo.suffix": {
"value": "a"
}
}
},
{
"term": {
"fields.foo.suffix": {
"value": "b"
}
}
}
]
}
}
}Root cause is src/Nest/CommonAbstractions/Infer/Field/Field.cs#L48 setting the expression to cacheable when there is a constant component to the expression.
Instead, CachableExpression should only be set when there are only constant expressions. You could check that there are no MemberAccess nodes (variable references are captured as members), but that wouldn't handle cases such as tqd.Field(td => td.fields[SomeFunction()]).
Provide ConnectionSettings (if relevant):
N/A
Provide DebugInformation (if relevant):
N/A