Search code examples
jsonelasticsearchnestedkibanajson-query

Elastic Nested query - display only the first 2 inner hits


How do I change my query to display only the 5 first orders within the orderbook?

My data is structure like this. Order is a nested type.

Orderbook
    |_ Orders

This is my query

  GET /orderindex/_search
    {
      "size": 10,
      "query": {
        "term": { "_type": "orderbook" }
      }
    } 

And this is the result

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 10,
    "max_score": 1,
    "hits": [
      {
        "_index": "orderindex",
        "_type": "orderbook",
        "_id": "1",
        "_score": 1,
        "_source": {
          "id": 1,
          "exchange": "Exch1",
          "label": "USD/CAD",
          "length": 40,
          "timestamp": "5/16/2018 4:33:31 AM",
          "orders": [
            {
              "pair1": "USD",
              "total": 0.00183244,
              "quantity": 61,
              "orderbookId": 0,
              "price": 0.00003004,
              "exchange": "Exch1",
              "id": 5063,
              "label": "USD/CAD",
              "pair2": "CAD",                
            },
            {
              "pair1": "USD",
              "total": 0.0231154,
              "quantity": 770,
              "orderbookId": 0,
              "price": 0.00003002,
              "exchange": "Exch1",
              "id": 5064,
              "label": "USD/CAD",
              "pair2": "CAD",
            },
             ...
              ..
               .

Also, how do I make to query two specific orderbooks by its label name and retrieve only the first 2 orders?

I am now sending of this query, but the problem is it is returning the orderbooks including all its orders and then after this it returns only 2 plus inners hits. How Do I do to return only the 2 inner hits without all the orders that are coming with the orderbook from the first part of the query

GET /orderindex/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": { "_type": "orderbook" }
        },
        {
          "nested": {
            "path": "orders",
            "query": {
              "match_all": {}
            },
            "inner_hits": {
              "size": 2 
            }
          }
        }
      ]
    }
  }}

Solution

  • Inner hits support the following options:

    size
    

    The maximum number of hits to return per inner_hits. By default the top three matching hits are returned.

    Which basically means, that you could do that, by using similar query

     {
      "query": {
        "bool": {
          "must": [
            {
              #replace this one with your query for orderbook
              "term": {
                "user": "kimchy"
              }
            },
            {
              "nested": {
                "path": "orders",
                "query": {
                  "match_all": {}
                },
                "inner_hits": {
                  "size": 3 #we asks for only 3 inner hits
                }
              }
            }
          ]
        }
      }
    }
    

    One could also would like to filter _source from results by doing this:

    "_source": {
            "includes": [ "obj1.*", "obj2.*" ],
            "excludes": [ "*.description" ]
        }
    

    In your case of orders - it could be useful to excludes orders.*

    More information on this one - https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-inner-hits.html