Matheus
Matheus

Reputation: 3370

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

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?

Upvotes: 1

Views: 118

Answers (1)

Bhavya
Bhavya

Reputation: 16172

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"
            }
          ]
        }
      }
    ]

Upvotes: 1

Related Questions