# Querying child objects of an indexed document (NEST)

**URL:** <https://discuss.elastic.co/t/querying-child-objects-of-an-indexed-document-nest/172815>\
**Category:** Elasticsearch\
**Created:** [March 18, 2019, 4:08pm UTC](https://discuss.elastic.co/t/querying-child-objects-of-an-indexed-document-nest/172815 "2019-03-18T16:08:18Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![lesscode](https://avatars.discourse-cdn.com/v4/letter/l/c5a1d2/32.png) [@lesscode](https://discuss.elastic.co/u/lesscode)\
**Post date:** [March 18, 2019, 4:08pm UTC](https://discuss.elastic.co/t/querying-child-objects-of-an-indexed-document-nest/172815/1 "2019-03-18T16:08:18Z")

</div>

I think I'm missing something fundamental with querying via the .NET client. We're trying to search log events logged via Serilog, with a context object nested as a field (using the Serilog ForContext mechanism).

```
EventLog eventLog = ...;
log.ForContext("EventLog", eventLog, true).Write(eventLog.EventMessage);

```

This results in documents that look like:

```
{
  "_index": "logstash-2019.03.14",
  "_type": "logevent",
  "_id": "p_amfGkBaphWeJXGjjSW",
  "_version": 1,
  "_score": null,
  "_source": {
    "@timestamp": "2019-03-14T09:41:21.6924251-05:00",
    "level": "Information",
    "messageTemplate": "blah",
    "message": "blah",
    "fields": {
      "EventLog": {
        "_typeTag": "EventLog",
        "EventMessage": "blah",
        "EventId": 3112,
...

```

It seems like the only way we can query on properties of these context objects is by using the string form of the object path (not using a type-safe expression on the POCO):

```
client.Search<Dummy>(s => s
    .AllTypes()
    .Query(q => q
        .Match(t => t
            .Field(f => f.Message).Query("blah"); // returns some results

client.Search<Dummy>(s => s
    .AllTypes()
    .Query(q => q
        .Match(t => t
            .Field(f => f.Fields.EventLog.EventMessage).Query("blah"); // returns zero results

client.Search<Dummy>(s => s
    .AllTypes()
    .Query(q => q
        .Match(t => t
            .Field(f => new Field("fields.EventLog.EventMessage")).Query("blah"); // returns some results

```

What am I missing?

UPDATE: I enabled query logging in ES and saw that there's a case difference between the literal and expression queries. The literal query (with PascalCased properties) is seen as Pascal cased by ES and finds the documents, while the type-safe expression gets converted to camelCase ("fields.eventLog.eventMessage"), and does not match anything. Sure enough, if I query with a literal camelCased field path, I get nothing back also.

How do I tell NEST to use the right case sensitivity?

---

<div class="post-metadata">

**Author:** ![forloop](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/forloop/32/9021_2.png) [@forloop](https://discuss.elastic.co/u/forloop)\
**Post date:** [March 19, 2019, 4:47am UTC](https://discuss.elastic.co/t/querying-child-objects-of-an-indexed-document-nest/172815/2 "2019-03-19T04:47:21Z")

</div>

You can control field infererence globally with `DefaultFieldNameInferrer` delegate; it accepts the CLR property name as input, and allows you to transform however you see fit. If unspecified, NEST will camelcase property names.

```auto
var settings = new ConnectionSettings()
    .DefaultFieldNameInferrer(p => p);

var client = new ElasticClient(settings);

```

Looking at the `_source` in the example provided, you're in a little bit of a tricky situation regarding inferring field names from CLR POCO property names because you have a mix of camel case at the top level, and pascal case under `"fields"`. You can apply attributes to POCO properties which NEST will use. For example

```auto
public class Dummy
{
    [PropertyName("fields")]
    public Fields Fields {get;set;}
}

public class Fields 
{
    [PropertyName("EventLog")]
    public EventLog EventLog {get;set;}
}

```

etc. You can use [`System.Runtime.Serialization.DataMemberAttribute`](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.datamemberattribute?view=netframework-4.7.2) instead of `Nest.PropertyNameAttribute`, if you prefer.

Then, lambda expressions will use these attribute values.

---

<div class="post-metadata">

**Author:** ![lesscode](https://avatars.discourse-cdn.com/v4/letter/l/c5a1d2/32.png) [@lesscode](https://discuss.elastic.co/u/lesscode)\
**Post date:** [March 19, 2019, 1:04pm UTC](https://discuss.elastic.co/t/querying-child-objects-of-an-indexed-document-nest/172815/3 "2019-03-19T13:04:27Z")

</div>

Thanks, Russ - that looks like exactly what I need. Serilog controls the "fields" part of the path written out to ES, and then logs the context objects and their properties with different case. Not sure why that is, but with these attributes we can take control over it, so it shouldn't matter.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [April 16, 2019, 1:04pm UTC](https://discuss.elastic.co/t/querying-child-objects-of-an-indexed-document-nest/172815/4 "2019-04-16T13:04:36Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
