Come risolvere gli errori relativi ad ElasticSearch su Neos, quando il mapping di alcuni tipi di campo non può essere modificato
Questo tipo di problema è solitamente causato da una configurazione errata sui file NodeTypes.yaml. Fondamentalmente, alcune proprietà non dovrebbero essere indicizzate ma lo sono effettivamente.
In particolare, potrebbero esserci alcuni campi che condividono lo stesso nome nella configurazione, ma in realtà utilizzano tipi diversi. Per questo motivo ElasticSearch su Neos restituirà un errore, perché prima trova il campo con quel nome e una tipologia specifica, poi lo ritrova con lo stesso nome ma di tipologia diversa.
Ad esempio, potremmo avere un campo "height" indicizzato due volte, una come tipo "stringa" e una come tipo "intero".
La causa dell'errore
Il riferimento [keyword] nell'errore si verifica solitamente con campi di tipo stringa. Questo è ciò che dovreste cercare nello YAML, il nome o il tipo del campo.
Supponiamo di avere questo file di configurazione:
# 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 questo caso, utilizziamo la stessa proprietà "height" due volte, una volta con il type: string e una con il type: integer.
La soluzione
Possiamo utilizzare nomi diversi per le nostre proprietà o, nel nostro caso, possiamo escludere il campo dall'indicizzazione di ElasticSearch, in questo modo:
properties:
height:
type: integer
search:
indexing: false
properties:
height:
type: string
search:
indexing: false
Quindi abbiamo aggiunto "search" allo stesso livello di "type", e poi "indexing: false" che va sotto l'impostazione "search".
Ora, poiché probabilmente avremo comunque altri problemi con i nostri indici ElasticSearch, possiamo eliminare tutti gli indici e ricostruirli di nuovo.
Eliminazione di tutti gli indici su ElasticSearch
Partiamo da questo. Possiamo eseguire il seguente comando sul nostro server, per inviare una query a ElasticSearch (dipende da come è configurato):
curl -X DELETE "localhost:9200/_all"
Questo eliminerà tutti gli indici. È rischioso? Probabilmente sì. Dovremmo evitarlo? Sarebbe meglio. Ma in alcuni casi, questo ti farà risparmiare ore di rimappatura e debug. In ogni caso sarà Neos ad occuparsi di ricostruire l’indice, come vedremo nel passaggio successivo. Almeno, per me ha funzionato bene e ho deciso per questo approccio dopo aver provato per più di 20 ore a cercare altre soluzioni meno drastiche, ma questa è stata l'unica che ha funzionato.
Ricostruire l'indice ElasticSearch da Neos con Flow
Eseguiamo ora questo comando sul nostro server:
php -d memory_limit=-1 flow nodeindex:build
Potremmo anche semplicemente eseguire `./flow nodeindex:build` ma nel mio caso l'indice era molto molto grande e avevo bisogno di aumentare il limite di memoria php da Plesk a 16G ed eseguire il commento con memory_limit impostato su -1 (che significa: utilizza tutta la memoria per questo processo).
Il sito non si è bloccato, quindi non preoccupiamoci troppo, dovrebbe andare bene, d'altro canto ci è voluto molto tempo, più di 20 minuti, e anche dopo così tanto, apparentemente ha esaurito la memoria (il processo, non il server nel suo insieme), tuttavia in questo caso avevo molti indici perché ci sono molte dimensioni (lingue) su questo sito web. Quindi credo che funzionerà meglio e più velocemente per siti più piccoli.
Crediti
Vorrei ringraziare i ragazzi della community di Neos su Slack che mi hanno dato utili suggerimenti su come risolvere questo problema!