I have an elastic search query:

{
    "query": {
            "bool": {
                "should": [
                    {'match_phrase': {'unique_chat_session_id': '1a8905a2-b328-4f57-8ce8-7ba2e43e138e'}}, {'match_phrase': {'unique_chat_session_id': 'f6a83c4a-8d2f-4f04-9eff-e753957fe9d2'}}
                ]
            }
        },
        "sort": [{"message_no": {"order": "asc"}}]
}

and output in below format:

    [
  {
    '_index': '',
    '_type': '',
    '_id': 'cPeZLG8BH6c52U24FH95',
    '_score': None,
    '_source': {
      'unique_chat_session_id': '1a8905a2-b328-4f57-8ce8-7ba2e43e138e',
      'message_no': 1
    },
    'sort': [
      1
    ]
  },
  {
    '_index': '',
    '_type': '',
    '_id': 'dPeZLG8BH6c52U24_X8k',
    '_score': None,
    '_source': {
      'unique_chat_session_id': 'f6a83c4a-8d2f-4f04-9eff-e753957fe9d2',
      'message_no': 1
    },
    'sort': [
      1
    ]
  },
  {
    '_index': '',
    '_type': '',
    '_id': 'cfeZLG8BH6c52U24FH_x',
    '_score': None,
    '_source': {
      'unique_chat_session_id': '1a8905a2-b328-4f57-8ce8-7ba2e43e138e',
      'message_no': 2
    },
    'sort': [
      2
    ]
  },
  {
    '_index': '',
    '_type': '',
    '_id': 'dfeZLG8BH6c52U24_X-w',
    '_score': None,
    '_source': {
      'unique_chat_session_id': 'f6a83c4a-8d2f-4f04-9eff-e753957fe9d2',
      'message_no': 2
    },
    'sort': [
      2
    ]
  },
  {
    '_index': '',
    '_type': '',
    '_id': 'cveZLG8BH6c52U24F3-c',
    '_score': None,
    '_source': {
      'unique_chat_session_id': '1a8905a2-b328-4f57-8ce8-7ba2e43e138e',
      'message_no': 3
    },
    'sort': [
      3
    ]
  },
  {
    '_index': '',
    '_type': '',
    '_id': 'c_eZLG8BH6c52U24GH8K',
    '_score': None,
    '_source': {
      'unique_chat_session_id': '1a8905a2-b328-4f57-8ce8-7ba2e43e138e',
      'message_no': 4
    },
    'sort': [
      4
    ]
  }
]

Now I want to make a query in which I will pass unique_chat_session_id in array format with exact match [1a8905a2-b328-4f57-8ce8-7ba2e43e138e, f6a83c4a-8d2f-4f04-9eff-e753957fe9d2] and I want to get the output result in the same way in which the array is. It should show all the result of 1st array element (here 1a8905a2-b328-4f57-8ce8-7ba2e43e138e) with sorting applied on msg_no. So my output result should be:

[
  {
    '_index': '',
    '_type': '',
    '_id': 'cPeZLG8BH6c52U24FH95',
    '_score': None,
    '_source': {
      'unique_chat_session_id': '1a8905a2-b328-4f57-8ce8-7ba2e43e138e',
      'message_no': 1
    },
    'sort': [
      1
    ]
  },
  {
    '_index': '',
    '_type': '',
    '_id': 'cfeZLG8BH6c52U24FH_x',
    '_score': None,
    '_source': {
      'unique_chat_session_id': '1a8905a2-b328-4f57-8ce8-7ba2e43e138e',
      'message_no': 2
    },
    'sort': [
      2
    ]
  },
  {
    '_index': '',
    '_type': '',
    '_id': 'cveZLG8BH6c52U24F3-c',
    '_score': None,
    '_source': {
      'unique_chat_session_id': '1a8905a2-b328-4f57-8ce8-7ba2e43e138e',
      'message_no': 3
    },
    'sort': [
      3
    ]
  },
  {
    '_index': '',
    '_type': '',
    '_id': 'c_eZLG8BH6c52U24GH8K',
    '_score': None,
    '_source': {
      'unique_chat_session_id': '1a8905a2-b328-4f57-8ce8-7ba2e43e138e',
      'message_no': 4
    },
    'sort': [
      4
    ]
  }
  {
    '_index': '',
    '_type': '',
    '_id': 'dPeZLG8BH6c52U24_X8k',
    '_score': None,
    '_source': {
      'unique_chat_session_id': 'f6a83c4a-8d2f-4f04-9eff-e753957fe9d2',
      'message_no': 1
    },
    'sort': [
      1
    ]
  },
  {
    '_index': '',
    '_type': '',
    '_id': 'dfeZLG8BH6c52U24_X-w',
    '_score': None,
    '_source': {
      'unique_chat_session_id': 'f6a83c4a-8d2f-4f04-9eff-e753957fe9d2',
      'message_no': 2
    },
    'sort': [
      2
    ]
  }
]
1

There are 1 best solutions below

0
On

If I understand your question correctly, you want to get back the documents in the sequence of unique_chat_session_id's as provided in the request, and then for a specific unique_chat_session_id ordered the documents by message_no.

As the first sorting criteria is not based on any logical order of values stored in your index, but solely relies on the position of the values in your request this cannot be accomplished with a query with sort-clauses.

You may want to consider using aggregations instead, where you first request the individual buckets in the order you want them, and then, for every single bucket, you request the top n hits.

Example:

POST /chat/_search
{
  "size": 0,
  "aggs": {
    "chat_sessions": {
      "filters": {
        "filters": [
          { "term": { "unique_chat_session_id.keyword": "1a8905a2-b328-4f57-8ce8-7ba2e43e138e" }},
          { "term": { "unique_chat_session_id.keyword": "f6a83c4a-8d2f-4f04-9eff-e753957fe9d2" }}
        ]
      },
      "aggs": {
        "messages_per_session": {
          "top_hits": {
            "sort": [
              { "message_no": { "order": "asc" }}
            ],
            "size" : 10
          }
        }
      }
    }
  }
}

The filtered buckets will be returned in the same order as provided in the request. But please be aware of the fact that the top_hits aggregation is not meant to return hundreds or thousands of documents, as its name implies it is ideal to return the first couple of hits, which you can control with the size parameter within the top_hits aggregation.

As you did not provide the mapping I assumed the default mapping for string-fields, which is as a multi field with unique_chat_session_id being mapped to a field of type text (ideal for full-text search, but not really sure whether this makes sense for your use-case) and unique_chat_session_id.keyword being mapped to a field of type keyword (ideal for exact match search, which is what you need in your example.