Socardo
Socardo

Reputation: 520

Elasticsearch NEST 2.x Field Names

I am upgrading to NEST 2.3.0 and trying to rewrite all queries that were originally written for NEST 1.x. I am using the Couchbase transport plugin that pushes data from Couchbase to Elasticsearch.

POCO

 public class Park
    {
        public Park()
        {

        }

        public bool IsPublic { get; set; }
    }

Mapping is like this

"mappings": {
"park": {
            "_source": {
                "includes": [
                  "doc.*"
                ],
                "excludes": [
                  "meta.*"
                ]
            },
            "properties": {
                "meta": {
                    "properties": {
                        "rev": {
                            "type": "string"
                        },
                      "flags": {
                        "type": "long"
                      },
                      "expiration": {
                        "type": "long"
                      },
                      "id": {
                        "type": "string",
                        "index": "not_analyzed"
                      }
                    }
                },
              "doc": {
                "properties": {

                  "isPublic": {
                    "type": "boolean"
                  }
                }
              }
            }
        }
      }

Sample document in elasticsearch

    {
  "_index": "parkindex-local-01",
  "_type": "park",
  "_id": "park_GUID",
  "_source": {
    "meta": {
      "expiration": 0,
      "flags": 33554433,
      "id": "park_GUID",
      "rev": "1-1441a2c278100bc00000000002000001"
    },
    "doc": {
      "isPublic": true,
      "id": "park_GUID"
    }
  }
}

My query in NEST

 var termQuery = Query<Park>.Term(p => p.IsPublic, true);
        ISearchResponse<T> searchResponse = this.client.Search<T>(s => s.Index("parkindex-local-01")
                     .Take(size)
                     .Source(false)
                     .Query(q => termQuery));

This query goes to Elasticsearch as below

{
  "size": 10,
  "_source": {
    "exclude": [
      "*"
    ]
  },
  "query": {
    "term": {
      "isPublic": {
        "value": "true"
      }
    }
  }
}

It doesn't retrieve any data, it will work only if I prefix the field name with "doc." so query becomes as below

{
  "size": 10,
  "_source": {
    "exclude": [
      "*"
    ]
  },
  "query": {
    "term": {
      "doc.isPublic": {
        "value": "true"
      }
    }
  }
}

How do I write the query above in NEST so it can properly interpret the field names, I tried using Nested Query with Path set to "doc", but that gave an error saying field is not of a nested type.

Do I need to change my mapping?

This all used to work in Elasticsearch 1.x and NEST 1.x, I guess this has to do with breaking changes to field names constraints.

Upvotes: 0

Views: 276

Answers (1)

Russ Cam
Russ Cam

Reputation: 125498

Fields can no longer be referenced by shortnames in Elasticsearch 2.0.

isPublic is a property of the doc field, which is mapped as an object type, so referencing by the full path to the property is the correct thing to do.

NEST 2.x has some ways to help with field inference, an example

public class Park
{
    public Doc Doc { get; set;}
}

public class Doc
{
    public bool IsPublic { get; set;}
}

var termQuery = Query<Park>.Term(p => p.Doc.IsPublic, true);

client.Search<Park>(s => s.Index("parkindex-local-01")
             .Take(10)
             .Source(false)
             .Query(q => termQuery));

results in

{
  "size": 10,
  "_source": {
    "exclude": [
      "*"
    ]
  },
  "query": {
    "term": {
      "doc.isPublic": {
        "value": true
      }
    }
  }
}

You may also want to take a look at the automapping documentation.

Upvotes: 0

Related Questions