Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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).

like image 962
Henk Kok Avatar asked Nov 07 '14 11:11

Henk Kok


1 Answers

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.

like image 168
keety Avatar answered Oct 12 '22 22:10

keety