La nostra API REST consente agli utenti di aggiungere JSON di schemi personalizzati ad alcune delle nostre risorse REST e abbiamo bisogno che siano ricercabili in Elasticsearch. Questi dati personalizzati e la sua struttura possono essere completamente diversi tra le risorse dello stesso tipo.Supporto Schemaless per query di ricerca elastica
considerare questo documento di esempio:
{
"givenName": "Joe",
"username": "joe",
"email": "[email protected]",
"customData": {
"favoriteColor": "red",
"someObject": {
"someKey": "someValue"
}
}
}
Tutti i campi ad eccezione customData
aderire a uno schema. customData
è sempre un oggetto JSON, ma tutti i campi e i valori all'interno di tale oggetto possono variare notevolmente da una risorsa all'altra. Non vi è alcuna garanzia che qualsiasi nome o valore di campo specificato (o anche il tipo di valore) all'interno di customData sia uguale tra le due risorse in quanto gli utenti possono modificare questi campi come desiderano.
Qual è il modo migliore per supportare la ricerca di questo?
Abbiamo pensato che una soluzione sarebbe semplicemente non creare alcuna mappatura per customData
quando l'indice è stato creato, ma poi diventa inaccessibile (che è contraria a ciò che è ES docs say). Questa sarebbe la soluzione ideale se le query su proprietà non mappate funzionassero e non ci fossero problemi di prestazioni con questo approccio. Tuttavia, dopo aver eseguito più test, non siamo riusciti a farlo funzionare.
È qualcosa che richiede una configurazione speciale? O i documenti sono errati? Sarebbe molto apprezzato qualche chiarimento sul motivo per cui non funziona.
Dal momento che questo non è attualmente lavorando per noi, abbiamo pensato a un paio di soluzioni alternative:
Reindicizzazione: questo sarebbe costoso come avremmo bisogno di reindicizzare ogni indice che contiene il documento e fare così ogni volta che un utente aggiorna una proprietà con un diverso tipo di valore. Davvero pessimo per le prestazioni, quindi probabilmente non è un'opzione reale.
Utilizzare multi-match query: faremolo aggiungendo una stringa casuale al nome del campo customData ogni volta che si modifica l'oggetto customData. Ad esempio, questo è ciò che il documento viene indicizzato sarebbe simile:
{ "givenName": "Joe", "username": "joe", "email": "[email protected]", "customData_03ae8b95-2496-4c8d-9330-6d2058b1bbb9": { "favoriteColor": "red", "someObject": { "someKey": "someValue" } } }
Ciò significa ES creerebbe una nuova mappatura per ogni campo 'random', e vorremmo usare l'espressione di query multi-partita con un "inizia con "jolly per i nomi dei campi durante l'esecuzione delle query. Per esempio:
curl -XPOST 'eshost:9200/test/_search?pretty' -d ' { "query": { "multi_match": { "query" : "red", "type" : "phrase", "fields" : ["customData_*.favoriteColor"] } } }'
questa potrebbe essere una soluzione praticabile, ma siamo preoccupati che avere troppi mappature come questo potrebbe influire sulle prestazioni. Ci sono ripercussioni sulla performance per avere troppe mappature su un indice? Forse la reindicizzazione periodica potrebbe alleviare troppe mappature?
Anche questo si sente come un hack e qualcosa che dovrebbe essere gestito da ES in modo nativo. Mi sto perdendo qualcosa?
Qualsiasi suggerimento su tutto ciò sarebbe molto apprezzato.
Grazie!
stai dicendo che il documento annidato può gestire la natura non deterministica descritta dell'oggetto 'customData'? –