Is it possible to get whole nested object from a document in Elasticsearch?

Viewed 44

Imagine I have a document like this:

{
  "_index": "bank-accounts",
  "_type": "_doc",
  "_id": "1",
  "_version": 4,
  "_seq_no": 3,
  "_primary_term": 1,
  "found": true,
  "_source": {
    "id": 1,
    "balance": 140,
    "transactions": [
      {
        "id": "42f52474-a49b-4707-86e4-e983efb4ab31",
        "type": "Deposit",
        "amount": 100
      },
      {
        "id": "3f8396a3-d747-4a4c-8926-cdcedea6b5c3",
        "type": "Deposit",
        "amount": 50
      },
      {
        "id": "5693585d-6356-4d1a-8d7b-cac5d0dab39f",
        "type": "Withdraw",
        "amount": 10
      }
    ],
    "accountCreatedAt": 1614029062764
  }
}

I do want to return only the transactions array in a query.

How would I do this within Elasticsearch? Is this even possible? I've achieved a result using fields[ "transactions.*" ], but it returns each of the fields in separate arrays:

{
    ...
    "hits": [
      {
        "_index": "bank-accounts",
        "_type": "_doc",
        "_id": "1",
        "_score": 1,
        "fields": {
          "transactions.id": [
            "42f52474-a49b-4707-86e4-e983efb4ab31",
            "3f8396a3-d747-4a4c-8926-cdcedea6b5c3",
            "5693585d-6356-4d1a-8d7b-cac5d0dab39f"
          ],
          "transactions.amount": [
            100,
            50,
            10
          ],
          "transactions.type": [
            "Deposit",
            "Deposit",
            "Withdraw"
          ],
          ...
        }
      }
    ]
  }
}

I mean, I could very well be using this, but I want something more simple to handle. I expect to get something like this:

*I have to use the document id in my search

{
    ...
    "hits": [
      {
        "_index": "bank-accounts",
        "_type": "_doc",
        "_id": "1",
        "_score": 3,
        "transactions": [
          {
            "id": "42f52474-a49b-4707-86e4-e983efb4ab31",
            "type": "Deposit",
            "amount": 100
          },
          {
            "id": "3f8396a3-d747-4a4c-8926-cdcedea6b5c3",
            "type": "Deposit",
            "amount": 50
          },
          {
            "id": "5693585d-6356-4d1a-8d7b-cac5d0dab39f",
            "type": "Withdraw",
            "amount": 10
          },
          ....
        ]
      }
    ]
  }
}

Is this possible to achieve?

1 Answers

If you only want to return the transactions array (as you have not mentioned any query condition, on which you need to search), you can achieve that using source filtering.

Adding a working example

Index Mapping:

{
  "mappings": {
    "properties": {
      "transactions": {
        "type": "nested"
      }
    }
  }
}

Index Data:

{
  "id": 1,
  "balance": 140,
  "transactions": [
    {
      "id": "42f52474-a49b-4707-86e4-e983efb4ab31",
      "type": "Deposit",
      "amount": 100
    },
    {
      "id": "3f8396a3-d747-4a4c-8926-cdcedea6b5c3",
      "type": "Deposit",
      "amount": 50
    },
    {
      "id": "5693585d-6356-4d1a-8d7b-cac5d0dab39f",
      "type": "Withdraw",
      "amount": 10
    }
  ],
  "accountCreatedAt": 1614029062764
}

Search Query:

{
  "_source": [
    "transactions.*"
  ]
}

Search Result:

"hits": [
      {
        "_index": "66324257",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "transactions": [
            {
              "amount": 100,
              "id": "42f52474-a49b-4707-86e4-e983efb4ab31",
              "type": "Deposit"
            },
            {
              "amount": 50,
              "id": "3f8396a3-d747-4a4c-8926-cdcedea6b5c3",
              "type": "Deposit"
            },
            {
              "amount": 10,
              "id": "5693585d-6356-4d1a-8d7b-cac5d0dab39f",
              "type": "Withdraw"
            }
          ]
        }
      }
    ]
Related