Neos CMS: How to solve error

Neos CMS: How to solve error "mapper cannot be changed from type [integer] to [keyword]"

Published at: 07/03/2024
Updated at: 07/03/2024
Categories
Tags

How to solve errors related to ElasticSearch on Neos, where some fields type mapping cannot be changed

This kind of problem is usually caused by some incorrect configuration on NodeTypes.yaml files. Basically, some properties should not be indexed but are actually being indexed.

In particular, there might be some fields that share the same name across the configuration, but actually use different types. For this reason, ElasticSearch on Neos will return an error, because it first finds the field with that name and one specific type, then finds it again with the same name but a different type.

For example, we could have a "height" field being indexed two times, one as a "string" type and one as an "integer" type.

The cause of the error

The [keyword] reference in the error happens usually with string type of fields. That is what you should look for in the YAML, either the name or the type of the field.

Let's say you have this configuration file:

# DistributionPackages\Customer.Lottie\Configuration\NodeTypes.Content.Lottie.yaml
'Customer.Lottie:Content.LottieImage':
  properties:
    height:
      type: string
      defaultValue: ""

# DistributionPackages\Customer.LoremIpsum.NodeTypes\Configuration\NodeTypes.Content.Divider.yaml
'Customer.LoremIpsum.NodeTypes:Content.Divider':
  properties:
    height:
      type: integer
      defaultValue: 1
      validation:
        'Neos.Neos/Validation/IntegerValidator': true
        'Neos.Neos/Validation/NumberRangeValidator':
          minimum: 0
          maximum: 255
        'Neos.Neos/Validation/NotEmptyValidator': true

In this case, you can see we use the same "height" property twice, once with the type: string and one with the type: integer.

The solution

We can either use different names for our properties or, in our case, we can exclude the field from being indexed by ElasticSearch, like this:

  properties:
    height:
      type: integer
      search:
        indexing: false

  properties:
    height:
      type: string
      search:
        indexing: false

So, we added "search" at the same level as "type", and then "indexing: false" that goes below the "search" setting.

Now, since we probably have some other problems with our ElasticSearch indexes anyway, we can delete all the indexes and rebuild them again.

Deleting all indexes on ElasticSearch

Let's start from this. We can run the following command on our server, to send a query to ElasticSearch (depends on how you configured it):

curl -X DELETE "localhost:9200/_all"

This will delete all the indexes. Is it risky? Probably yes. Should you avoid it? Most likely. But in some cases, this will save you hours of remapping and debugging. In any case, Neos will take care of rebuilding the index, as we will see in the next step. At least, it worked well for me, and I decided for this approach after trying for 20+ hours to go for other less catastrophic solutions, but this was the only one that worked.

Rebuiling the ElasticSearch index from Neos with Flow

Let's now run this command on our server:

php -d memory_limit=-1 flow nodeindex:build

You could even just run `./flow nodeindex:build` but in my case the index was very very large, and I needed to increase the php memory limit from Plesk to 16G and run the comment with memory_limit set to -1 (meaning: use all the memory for this process).

It did not crash the site for me, so don't worry, you should be fine, on the other hand tho it took a very long time, more thank 20 minutes, and even after that it apparently ran out of memory (the process, not the server as a whole) but I have many indexes because there are many dimensions (languages) on this website. Therefore I believe it will work better and faster in your case, unless you also have a huge website.

Credits

I would like to thank the guys from Neos Slack community that gave me useful hints on how to solve this!

Leave a comment

All comments will be subject to approval after being sent. They might be published after several hours.

You can just use a random nickname, it is usefull to allow me to at least answer your comments. And if you choose to submit your email, you can receive a notification whenever I reply to your comment.

No comments have been written so far on this article. Be the first to share your thoughts!

*