How to get search results with exact matches sorted by popularity within themselves and then partial matches sorted by popularity within themselves?

Hello Elastic community,

I am new to Elasticsearch and feel lost as to how to accomplish this.
I have tried a lot of different things, but was not able to accomplish this.

Let me explain the expected search results with an example:
When searching for "dog" I expect following search result:

  1. First in the results are records, that have an exact match "dog" in tags.name and are sorted by popularity.
  2. Then I want results, that have (partial) matches (e.g. "hot dog" or "corn-dog" or "hotdog") in description or tags.name or categories.name also sorted by popularity.

This is how the data record of an exact match looks like:

{
  categories: [ { id: 1, name: 'Animals' } ],
  description: 'Sleeping dog wakes up as owner comes home. Cute puppy dog taking a nap. ',
  id: 4927,
  popularity: 5,
  tags: [
    { id: 7251, name: 'animal' },
    { id: 7255, name: 'canine' },
    { id: 7258, name: 'dog' },
    { id: 7261, name: 'fur' },
    { id: 7267, name: 'pet' },
  ]
}

This is how the data of a partial match can look like:

{
  categories: [
    { id: 8, name: 'Food and Drink' },
    { id: 14, name: 'Nature' },
    { id: 16, name: 'People' }
  ],
  description: 'Grilling a hotdog in a park on independence day. Holiday bbq with diverse group of friends. Grilling a hotdog for friends.',
  id: 5227,
  popularity: 2,
  tags: [
    { id: 7038, name: 'day' },
    { id: 7104, name: 'people' },
    { id: 7195, name: 'holiday' },
    { id: 7262, name: 'happy' },
    { id: 7289, name: 'food' },
    { id: 7344, name: 'dolly' },
    { id: 7523, name: 'eat' },
    { id: 7664, name: 'tasty' },
    { id: 7975, name: 'sunset' },
    { id: 8384, name: 'outdoors' },
    { id: 8772, name: 'dusk' },
    { id: 8808, name: 'bbq' },
    { id: 8830, name: 'free' },
    { id: 8831, name: 'hotdog' },
    { id: 8832, name: 'partk' },
    { id: 8833, name: 'ketchup' },
    { id: 8834, name: 'mustard' },
    { id: 8835, name: 'squirt' },
    { id: 8836, name: 'day outside' },
    { id: 9845, name: 'Exterior' }
  ]
}

This is the current mapping:

mappings: {
  properties: {
    tags: {
      type: 'nested',
      properties: {
        name: {
          type: 'text',
          fields: {
            raw: {
              type:  'keyword'
            }
          }
        },
        id: { type: 'integer', index: false }
      }
    },
    categories: {
      type: 'nested',
      properties: {
        name: { type: 'text' },
        id: { type: 'integer', index: false }
      }
    },
    description: { type: 'text' },
    popularity: {type: 'integer', index: false }
  }
}

This is the search query so far:

{
  from: 0,
  size: 12,
  query: {
    bool: {
      should: [
        {
          nested: {
            path: 'tags',
            query: {
              term: {
                'tags.name.raw': {
                  value: 'dog',
                  boost: 7
                }
              }
            }
          }
        },
        {
          multi_match: {
            query: 'dog',
            fields: ['tags.name', 'description'],
            type: 'most_fields'
          }
        }
      ]
    }
  },
  sort: [
    { popularity: 'desc' },
    '_score'
  ]
}

Unfortunately, I only get the exact matches sorted by popularity returned not the partial matches.
Help would be very much appreciated.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.