Quando si crea un indice per una colonna, i valori nella colonna vengono utilizzati letteralmente come le chiavi dell'indice. Nel tuo caso, i tasti per l'indice bitrates
sarebbero gli oggetti all'interno della matrice bitrates
nel documento.
Sembra che quello che vuoi sia un indice derivato dai valori in un campo del documento. Per fare ciò, si desidera definire una funzione di indicizzazione personalizzata che riduca il documento ai soli dati a cui tieni. Il modo più semplice per sperimentarli è iniziare scrivendo una query e, una volta soddisfatti dei risultati, convertirla in un'istruzione indexCreate()
.
Ecco una dichiarazione che afferra il vostro documento di esempio (con id 1), e pizzica le format
e rate
termini da tutti gli oggetti nella sua bitrate
array, e poi li fonde insieme per creare una serie distinta di stringhe:
r.db('music').table('catalog').get(1).do(function(row) {
return row('bitrates').map(function(bitrate) {
return [bitrate('format'), bitrate('rate')];
}).reduce(function(left, right) {
return left.setUnion(right);
})
})
l'esecuzione di questa dichiarazione restituirà il seguente:
["mp3", "128K", "aac", "192K"]
questo sembra buono, in modo che possiamo usare la nostra funzione per creare un indice. In questo caso, dal momento che ci aspettiamo la funzione di indicizzazione per restituire un insieme di elementi, anche noi vogliamo specificare {multi: true}
per assicurarci di poter interrogare dai voci nel set, non è il set in sé:
r.db('music').table('catalog').indexCreate('bitrates', function(row) {
return row('bitrates').map(function(bitrate) {
return [bitrate('format'), bitrate('rate')];
}).reduce(function(left, right) {
return left.setUnion(right);
})
}, {multi: true})
Una volta creato, è possibile interrogare l'indice in questo modo:
r.db('music').table('catalog').getAll('mp3', {index: 'bitrates'})
È possibile anche fornire più termini di ricerca, in modo che corrisponda righe che corrispondono uno qualsiasi degli elementi:
r.db('music').table('catalog').getAll('mp3', '128K', {index: 'bitrates'})
Tuttavia, se un singolo documento corrisponde a più di un termine nella query, verrà restituito più di una volta.Per risolvere questo problema, aggiungere distinct()
:
r.db('music').table('catalog').getAll('mp3', '128K', {index: 'bitrates'}).distinct()
Se necessario, si potrebbe anche considerare l'utilizzo di downcase()
per normalizzare l'involucro dei termini utilizzati nella indice secondario.
Si potrebbe anche saltare tutte le attività di indicizzazione del tutto e utilizzare una query filter()
:
r.db('music').table('catalog').filter(function(row) {
return row('bitrates').map(function(bitrates) {
return [bitrates('format'), bitrates('rate')];
}).reduce(function(left, right) {
return left.setUnion(right);
}).contains('mp3');
})
Detto questo, se si sta quasi sempre interrogare il vostro tavolo allo stesso modo, generando un indice secondario utilizzando un la funzione personalizzata si tradurrà in prestazioni notevolmente migliori.
Grazie Nate - grande risposta! Penso che avrei dovuto aggiungere nella mia descrizione che il mio obiettivo era usare un multiindice su una serie di oggetti e suona come se ciò non fosse possibile con un up up '{multi: true}'. Questa è più di una cosa esplorativa che sto facendo - in entrambi i casi la tua risposta è stellare grazie :) –