NEST fluent dsl queries - RequestBodyInBytes are always byte[2]

Hi all,

I'm sending a very simple query with the following code, but when I try to debug and see what was actually posted in the body, it's always practically empty (byte[2], to be exact). Could somebody please tell me what I'm missing?

Here's the code :

      var node = new Uri("http://localhost:9200");
        var settings = new ConnectionSettings(node).DefaultIndex("loandetails");
        settings.EnableDebugMode();
        var client = new ElasticClient(settings);
        var results = client.Search<LoanDetail>(s => s
            .Query(a => a
                .Bool(b => b
                    .Must(c => c
                            .Match(i => i
                                .Field(l => l.Id)
                                .Name("568e8515fbffa90f107f5083")
                            )
                    )
                )
            )
        ); 

And here's how I'm seeing the request:

results.ApiCall.RequestBodyInBytes

...which, when converted, turns into this: {}

Any help would be greatly appreciated.

The specified match query does not have a query property. As such, you're hitting a feature in NEST known as Conditionless queries; for a match query, is is considered conditionless when:

  1. the field is conditionless (null expression, PropertyInfo, string or empty string)
  2. or the query is null or empty
  3. or both 1. and 2.

When a query is considered conditionless it does not form part of the serialized json for the query DSL. You can change this behaviour on a per query basis with strict and verbatim queries.

Conditionless queries are useful because it means you don't need to perform all sorts of if/else branching yourself to include queries in a composite query if values are null or empty.

In this particular case, you can fix the issue by providing the query part (which I think is what you meant to provide :smile:):

   var node = new Uri("http://localhost:9200");
    var settings = new ConnectionSettings(node).DefaultIndex("loandetails");
    settings.EnableDebugMode();
    var client = new ElasticClient(settings);

    var results = client.Search<LoanDetail>(s => s
        .Query(a => a
            .Bool(b => b
                .Must(c => c
                        .Match(i => i
                            .Field(l => l.Id)
                            .Query("568e8515fbffa90f107f5083")
                        )
                )
            )
        )
    );

I understand. I thought that to translate the following using fluent DSL:

"must":
[
{
"match": {
"Id": "568e8515fbffa90f107f5083"
}
}
]

I had to write:

.Must(c => c
.Match(i => i
.Field(l => l.Id)
.Name("568e8515fbffa90f107f5083")
)
)

I didn't realize the Match function doesn't default to forming a "query."

Thanks for yet another amazingly quick reply.

It does, but you've used .Name() which gives a query a name so that you can identify it in a response, useful when you have a complex compound query. To add a query part for a match query, you need to use .Query().

"match": {
    "Id": "568e8515fbffa90f107f5083"
}

is a short form for the longer form

"match": {
    "Id": {
       "query": "568e8515fbffa90f107f5083"
    }
}

(As an aside: NEST supports only the long form of the query when both serializing to JSON and deserializing from JSON).

Very good to know. Thanks again.