Filtro MongoDB in base a molti parametri (indice composto o meno)
-
29-10-2019 - |
Domanda
Ho un catalogo con i prodotti e voglio filtrarlo in base a molti parametri: categoria, prezzo, taglia, colore, peso ecc.
Quindi la domanda riguarda l'indicizzazione.
Posso provare a utilizzare l'indice composto su tutti i campi e interrogarli nello stesso ordine in cui li ho indicizzati. Ma cosa succede se devo filtrare solo per taglia e colore e solo per prezzo e peso? La creazione di un indice composto per ogni possibile query di filtraggio sarebbe eccessiva perché potrebbero esserci troppi parametri.
Quindi, dopo alcune ricerche ho trovato un approccio interessante
Si suggerisce di utilizzare "attributi normalizzati":
{color: "red"} = 10
{weight: 125} = 25
{size: "M"} = 30
e ora il record di mongo sarà simile a questo:
{_id: ..., attributes: [10,25,30]}
Quindi dovrei indicizzare per attributi e successivamente posso interrogare in questo modo:
db.items.find(attributes: {$all: [10,25,30]})
I vantaggi sono:
- indici più piccoli
- ricerche più veloci
- un numero qualsiasi di parametri
- facile crescita
Quello che non ho capito è COME ottengo quei numeri per ogni attributo? Sono calcolati in qualche modo (come md5)? O devo creare una raccolta diversa e memorizzare ogni numero-chiave-valore lì? E ottenere prima i numeri da lì - ogni volta che devo filtrare la raccolta "elementi"?
E cosa ne pensi di questo approccio?
AGGIORNAMENTO: E se utilizzassi stringhe concatenate invece di numeri?
{_id: ..., attributes: ["language.English", "color.red"]}
Soluzione
La ricerca (efficiente) nel catalogo di un negozio è in effetti un compito non banale.
Sì, puoi creare una raccolta aggiuntiva e memorizzare tutti i valori lì
{name: "language", value: "English", numValue: "13"}
No, non è necessario eseguire nuovamente una query su questa raccolta ogni volta.La dimensione dei dati qui sarà probabilmente piccola, quindi puoi memorizzarla nella cache nel processo di applicazione.Non dimenticare il suggerimento: metti sempre prima l'attributo con la cardinalità più bassa.
Un altro approccio potrebbe essere quello di utilizzare il mascheramento dei bit, ma poiché MongoDB ha una lunghezza intera limitata, non è possibile ottenere un numero illimitato di attributi.