# How can I sort strings with numbers alphabetically?

**URL:** <https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088>\
**Category:** Elasticsearch\
**Created:** [November 16, 2022, 2:21pm UTC](https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088 "2022-11-16T14:21:30Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michal\_Stefaniuk](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/michal_stefaniuk/32/113425_2.png) [@Michal\_Stefaniuk](https://discuss.elastic.co/u/Michal_Stefaniuk)\
**Post date:** [November 16, 2022, 2:21pm UTC](https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088/1 "2022-11-16T14:21:30Z")

</div>

Hey guys, one quick question.

I have a set of example records:

```auto
Test
123 sesi
501 Alva
rout

```

and I want those to be sorted in asc/desc order in case insensitive and alphabeticall order, just like this:

```auto
501 Alva
rout
123 sesi
Test

```

so as you can see the first letter is dictating the order from A-Z (or other way around).

How can I achieve that? Right now what I was able to achieve is case insensitive sorting through the normalizer so it sorts like this:

```auto
123 sesi
501 Ava
rout
Test

```

but the problem is that numbers are being sorted first and then the letters. Any ideas how can I solve this? I'm sharing with you guys my current configuration.

```auto
      "normalizer": {
        "my_normalizer": {
          "type": "custom",
          "char_filter": [],
          "filter": ["lowercase", "asciifolding"]
        }
      }

```

and then I'm using is as:

```auto
  "mappings": {
    "dynamic_templates": [
            {
        "data_key": {
          "mapping": {
            "type": "keyword",
            "normalizer": "my_normalizer",
            "index_options": "docs",
            "copy_to": "all_search_fields"
          },
          "match": "*_*_key"
        }
      },
      {
        "data_string": {
          "mapping": {
            "norms": false,
            "type": "text",
            "fields": {
              "raw": {
                "type": "keyword",
                "index_options": "docs",
                "normalizer": "my_normalizer"
              }
            },
            "index_options": "positions",
            "copy_to": "all_search_fields"
          },
          "match": "*_*_string"
        }
      }
      ]

```

---

<div class="post-metadata">

**Author:** ![RabBit\_BR](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/rabbit_br/32/82261_2.png) [@RabBit\_BR](https://discuss.elastic.co/u/RabBit_BR)\
**Post date:** [November 16, 2022, 4:02pm UTC](https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088/2 "2022-11-16T16:02:45Z")

</div>

You can to use char\_filter to remove number in text and then add it in your normalizer.

Like this:

```auto
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "normalizer": {
        "my_normalizer": {
          "type": "custom",
          "char_filter": [
            "my_char_filter"
          ],
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "pattern_replace",
          "pattern": """(\d+ )""",
          "replace": ""
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "description": {
        "type": "text",
        "fields": {
          "raw": {
            "type": "keyword",
            "index_options": "docs",
            "normalizer": "my_normalizer"
          }
        }
      }
    }
  }
}

POST my-index-000001/_bulk
{"index":{}}
{"description":"Test"}
{"index":{}}
{"description":"123 sesi"}
{"index":{}}
{"description":"501 Alva"}
{"index":{}}
{"description":"rout"}

POST my-index-000001/_search?filter_path=hits.hits._source
{
 "sort": [
   {
     "description.raw": {
       "order": "asc"
     }
   }
 ]
}

```

Reponse:

```auto
{
  "hits": {
    "hits": [
      {
        "_source": {
          "description": "501 Alva"
        }
      },
      {
        "_source": {
          "description": "rout"
        }
      },
      {
        "_source": {
          "description": "123 sesi"
        }
      },
      {
        "_source": {
          "description": "Test"
        }
      }
    ]
  }
}

```

---

<div class="post-metadata">

**Author:** ![Michal\_Stefaniuk](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/michal_stefaniuk/32/113425_2.png) [@Michal\_Stefaniuk](https://discuss.elastic.co/u/Michal_Stefaniuk)\
**Post date:** [November 16, 2022, 4:28pm UTC](https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088/3 "2022-11-16T16:28:31Z")

</div>

Thanks for this hint!

Though now after applying that filter I'm facing this exception

```auto
Elasticsearch exception [type=illegal_argument_exception, reason=unknown setting [index.char_filter.my_char_filter.type] please check that any required plugins are installed, or check the breaking changes documentation for removed settings]

```

any idea what could be the reason?

---

<div class="post-metadata">

**Author:** ![RabBit\_BR](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/rabbit_br/32/82261_2.png) [@RabBit\_BR](https://discuss.elastic.co/u/RabBit_BR)\
**Post date:** [November 16, 2022, 4:38pm UTC](https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088/4 "2022-11-16T16:38:21Z")

</div>

what is your version ES?

---

<div class="post-metadata">

**Author:** ![Michal\_Stefaniuk](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/michal_stefaniuk/32/113425_2.png) [@Michal\_Stefaniuk](https://discuss.elastic.co/u/Michal_Stefaniuk)\
**Post date:** [November 16, 2022, 4:53pm UTC](https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088/5 "2022-11-16T16:53:33Z")

</div>

Ok, so my mistake, sorry. Apparently I've placed the char\_filter outside **analysis**. Now I've placed it inside and the application is building.

But, the sorting still works exactly the same as before.

@RabBit_BR - are you sure that the pattern should be `"pattern": """(\d+ )"""` ? Those three quotation marks are raising my concerns.

```auto
ElasticsearchParseException[Failed to parse content to map]; nested: JsonParseException[Unexpected character ('"' (code 34)): was expecting comma to separate Object entries

```

edit: Im using image **elasticsearch:7.16.1**

---

<div class="post-metadata">

**Author:** ![RabBit\_BR](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/rabbit_br/32/82261_2.png) [@RabBit\_BR](https://discuss.elastic.co/u/RabBit_BR)\
**Post date:** [November 16, 2022, 5:00pm UTC](https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088/6 "2022-11-16T17:00:54Z")

</div>

> [@Michal\_Stefaniuk](#):
>
> are you sure that the pattern should be `"pattern": """(\d+ )"""` ?

Yes. But you can change to:

` "pattern": "(\\d+ )"`

---

<div class="post-metadata">

**Author:** ![Michal\_Stefaniuk](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/michal_stefaniuk/32/113425_2.png) [@Michal\_Stefaniuk](https://discuss.elastic.co/u/Michal_Stefaniuk)\
**Post date:** [November 16, 2022, 5:30pm UTC](https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088/7 "2022-11-16T17:30:04Z")

</div>

Ok, so I went for

```auto
      "normalizer": {
        "my_normalizer": {
          "type": "custom",
          "char_filter": ["my_char_filter"],
          "filter": ["lowercase", "asciifolding"]
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "pattern_replace",
          "pattern": "(\\d+ )",
          "replace": ""
        }
      }

```

and of course added it to my type mapping.

Now it works like a charm, thanks @RabBit_BR , I owe you a large beer 🍻!

---

<div class="post-metadata">

**Author:** ![Michal\_Stefaniuk](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/michal_stefaniuk/32/113425_2.png) [@Michal\_Stefaniuk](https://discuss.elastic.co/u/Michal_Stefaniuk)\
**Post date:** [November 17, 2022, 4:01pm UTC](https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088/8 "2022-11-17T16:01:16Z")

</div>

@RabBit_BR I have one more question, sorry to bother. I noticed one more thing.

Let's say I have a set of data:

```auto
Bstring
4 alpha
3 alpha

```

and I sort it with my number-ignoring and case insensitive normalizer then the output is

```auto
4 alpha
3 alpha
Bstring

```

but I think it would be amazing to add one more thing. Is it possible to achieve this output?

```auto
3 alpha
4 alpha
Bstring

```

So the real question is - if you have two equal string that start with different numbers, can we add numerical sorting to those?

---

<div class="post-metadata">

**Author:** ![RabBit\_BR](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/rabbit_br/32/82261_2.png) [@RabBit\_BR](https://discuss.elastic.co/u/RabBit_BR)\
**Post date:** [November 17, 2022, 4:38pm UTC](https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088/9 "2022-11-17T16:38:16Z")

</div>

you can try something. You will have another field that indexes as a keyword.  
In luck you will have a tiebreaker which is this new field.

Would be like this:

```auto
{
   "sort": [
     {
       "description.raw": {
         "order": "asc"
       }
     },
     {
       "description.keyword": {
         "order": "asc"
       }
     }
   ]
  }

```

All example:

```auto
PUT my-index-000001
{
  "settings": {
    "analysis": {
      "normalizer": {
        "my_normalizer": {
          "type": "custom",
          "char_filter": [
            "my_char_filter"
          ],
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "pattern_replace",
          "pattern": """(\d+ )""",
          "replace": ""
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "description": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword"
          },
          "raw": {
            "type": "keyword",
            "index_options": "docs",
            "normalizer": "my_normalizer"
          }
        }
      }
    }
  }
}

POST my-index-000001/_bulk
{"index":{}}
{"description":"Test"}
{"index":{}}
{"description":"123 sesi"}
{"index":{}}
{"description":"501 Alva"}
{"index":{}}
{"description":"rout"}
{"index":{}}
{"description":"Bstring"}
{"index":{}}
{"description":"4 alpha"}
{"index":{}}
{"description":"3 alpha"}

POST my-index-000001/_search?filter_path=hits.hits._source
{
 "sort": [
   {
     "description.raw": {
       "order": "asc"
     }
   },
   {
     "description.keyword": {
       "order": "asc"
     }
   }
 ]
}

```

Response

```auto
{
  "hits": {
    "hits": [
      {
        "_source": {
          "description": "3 alpha"
        }
      },
      {
        "_source": {
          "description": "4 alpha"
        }
      },
      {
        "_source": {
          "description": "501 Alva"
        }
      },
      {
        "_source": {
          "description": "Bstring"
        }
      },
      {
        "_source": {
          "description": "rout"
        }
      },
      {
        "_source": {
          "description": "123 sesi"
        }
      },
      {
        "_source": {
          "description": "Test"
        }
      }
    ]
  }
}

```

---

<div class="post-metadata">

**Author:** ![Michal\_Stefaniuk](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/michal_stefaniuk/32/113425_2.png) [@Michal\_Stefaniuk](https://discuss.elastic.co/u/Michal_Stefaniuk)\
**Post date:** [November 17, 2022, 5:11pm UTC](https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088/10 "2022-11-17T17:11:04Z")

</div>

I was thinking about something similar, but I'm using dynamic\_templates, can both solutions be mixed together?

My settings looks like this

```auto
"settings": {
    "analysis": {
      "normalizer": {
        "my_normalizer": {
          "type": "custom",
          "char_filter": ["my_char_filter"],
          "filter": ["lowercase", "asciifolding"]
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "pattern_replace",
          "pattern": "(\\d+ )",
          "replace": ""
        }
      }
    }
}

```

a then the mappings

```auto
  "mappings": {
    "dynamic_templates": [
      {
        "data_key": {
          "mapping": {
            "type": "keyword",
            "normalizer": "my_normalizer",
            "index_options": "docs",
            "copy_to": "all_search_fields"
          },
          "match": "*_*_key"
        }
      },
      {
        "data_string": {
          "mapping": {
            "norms": false,
            "type": "text",
            "fields": {
              "raw": {
                "type": "keyword",
                "index_options": "docs",
                "normalizer": "my_normalizer"
              }
            },
            "index_options": "positions",
            "copy_to": "all_search_fields"
          },
          "match": "*_*_string"
        }
      }
    ]
}

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [December 15, 2022, 5:11pm UTC](https://discuss.elastic.co/t/how-can-i-sort-strings-with-numbers-alphabetically/319088/11 "2022-12-15T17:11:37Z")

</div>

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