Henk Kok
Henk Kok

Reputation: 383

Elasticsearch NEST - Filtering on multilevel nested types

I have a document model like this:

"customer": {  
    "properties": {  
        "id": { "type": "integer" },
        "name": { "type": "string" },
        "orders": {
            "type": "nested",
            "properties": {
                "id": { "type": "integer" },
                "orderDate" : { "type": "date", "format" : "YYYY-MM-dd" },
                "orderLines": {
                    "type": "nested",
                    "properties": {
                        "seqno": { "type": "integer" },
                        "quantity": { "type": "integer" },
                        "articleId": { "type": "integer" }
                    }
                }
            }
        }
    }
}  

A customer can have 0, 1 or multiple orders and an order can have 0, 1 or multiple orderLines
(this is a model I created for this question, as I think this is data everyone can understand, so if you spot any mistakes, please let me know, but don't let them distract you from my actual question)

I want to create a query with NEST which selects a (or all) customers with a specific value for customer.id, but only if they have at least one orderLine with a specific articleId.

I've looked at Need concrete documentation / examples of building complex index using NEST ElasticSearch library and Matching a complete complex nested collection item instead of separate members with Elastic Search, but was unable to create the query. Based upon the second question, I got to the point where I wrote

var results = client.Search<customer>(s => s
    .From(0)
    .Size(10)
    .Types(typeof(customer))
    .Query(q =>
        q.Term(c => c.id, 12345)
        && q.Nested(n => n
            .Path(c => c.order)
            .Query(q2 => q2.Nested(n2 => n2
                .Path(o => o.???))))
             )
            );

I expected the second Path to use order (orders is List) as generic type, but it is customer.

What is the code for the correct query?

In addition: is there more elaborate documentation of the search/query/filtering methods of NEST than the documentation on http://nest.azurewebsites.net/? In the first referenced question, both the links to the complex query tutorial (in question) and the unit test examples (accepted answer) do not work (timeout and 404 respectively).

Upvotes: 7

Views: 9259

Answers (1)

keety
keety

Reputation: 17461

Assuming we are modelling the customer to something on these lines

class customer
    {
        public int id { get; set; }
        public string name { get; set;}

        public class Orders {
            public int id { get; set;}
            public string orderData { get; set;}
            public class OrderLines
            {
                public int seqno { get; set; }
                public int quantity { get; set; }
                public int articleId { get; set; }
            }
            [ElasticProperty(Type = FieldType.Nested)]
            public List<OrderLines> orderLines { get; set; }
        }
         [ElasticProperty(Type = FieldType.Nested)]
        public List<Orders> orders { get; set; }

    };

The query in the above case would be :

 var response = client.Search<customer>(
                s => s.Index(<index_name_here>).Type("customer")
                .Query(q => q.Term(p=>p.id, 1) 
                &&
                q.Nested(n =>
                    n.Path("orders")
                    .Query(q2=> q2.Nested(
                        n2 => n2.Path("orders.orderLines")
                        .Query(q3 => 
                            q3.Term(c=>c.orders.First().orderLines.First().articleId, <article_id_here>)))))
               ));

As far as documentation the best I have come across is the same as the one you posted in the question and the resources linked there.

Upvotes: 10

Related Questions