2012-04-30 10 views
5

Ho ottenuto milioni di elementi ordinati da un punteggio precompilato. Ogni elemento ha molti attributi booleani. Diciamo che ci sono circa diecimila possibili attributi in totale, ogni oggetto ne ha decine.Soluzione di datastore per la ricerca di tag

Mi piacerebbe poter richiedere in tempo reale (pochi millisecondi) i primi n elementi dati ~ qualsiasi combinazione di attributi.

Quale soluzione consiglieresti? Sto cercando qualcosa di estremamente scalabile.

-
- Al momento stiamo esaminando MongoDB e array di tipo indice, si vede alcuna limitazione?
- SolR è una possibile soluzione, ma non abbiamo bisogno di funzionalità di ricerca testuale.

+1

quando dici "ordinato per punteggio" vuoi dire che questo è già precompilato? In tal caso, SOLR potrebbe non fornire alcun vantaggio. In caso contrario, SOLR fornisce un ranking di pertinenza molto potente e personalizzabile. – nickdos

+0

Milioni di elementi non rappresentano un problema per SOLR, ma 10.000 possibili attributi potrebbero essere un problema. SOLR supporta i campi dinamici in modo da non dover definire tutti gli attributi, ma la memoria potrebbe esplodere con uno schema ampio/spartano? Altri potrebbero essere in grado di consigliarlo meglio. – nickdos

+0

@nickdos si il punteggio è precalcolato. E penso che tu abbia ragione la parte difficile è il gran numero di attributi. Non so come gestirlo mongodb. Crea un indice per attributi? È persino possibile avere tanti indici? Stiamo andando a testare comunque, ma mi piacerebbe essere sicuri di non perdere la strategia corretta. – log0

risposta

9

MongoDB in grado di gestire ciò che si vuole, se memorizzato gli oggetti come questo

{ score:2131, attributes: ["attr1", "attr2", "attr3"], ... } 

Poi la seguente query corrisponderà tutti gli elementi che hanno ATT1 e attr2

c = db.mycol.find({ attributes: { $all: [ "attr1", "attr2" ] } }) 

ma questo ha vinto' t corrisponde a

c = db.mycol.find({ attributes: { $all: [ "attr1", "attr4" ] } }) 

la query restituisce un cursore, se si desidera ordinare questo cursore, t gallina basta aggiungere i parametri di ordinamento alla query in questo modo

c = db.mycol.find({ attributes: { $all: [ "attr1", "attr2" ] }}).sort({score:1}) 

Dai un'occhiata alla Advanced Queries per vedere ciò che è possibile.

indici appropriati può essere configurato come segue

db.mycol.ensureIndex({attributes:1, score:1}) 

E si può ottenere informazioni sulle prestazioni utilizzando

db.mycol.find({ attributes: { $all: [ "attr1" ] }}).explain() 

Mongo spiega come molti oggetti sono stati esaminati, per quanto tempo l'operazione ha preso e varie altre statistiche .

+0

In effetti mongodb sembra adattarsi molto bene al bisogno, ma mi preoccupo dell'efficienza. Non hai menzionato gli indici qui. È un indice su attributi e punteggi sufficienti nel mio caso ... – log0

+0

Ho aggiunto informazioni sugli indici. Assicurati che tutti gli indici si adattino alla memoria, altrimenti le tue query rallenteranno. –

+0

Ho letto da qualche parte che potrebbero esserci al massimo 64 indici su una collezione. Cosa succede in caso di array indicizzato? Significa che mongo creerà 10.000 indici? – log0

2

Questo è esattamente ciò che può gestire Mongo. Il fatto che i tuoi attributi siano di tipo booleano aiuta qui. Un possibile schema è riportato di seguito:

[ 
    { 
     true_tags:[attr1, attr2, attr3, ...], 
     false_tags: [attr4, attr5, attr6, ...] 
    }, 
] 

allora possiamo indice su true_tags e false_tags. E dovrebbe essere efficiente per cercare con $ in, $ tutti, ... operatori di query.

+0

Spiacente, non è stato molto chiaro, ma per booleano intendevo che l'elemento ha o meno l'attributo. La tua risposta è ancora valida, ma sto cercando informazioni più precise. C'è una limitazione su quel tipo di indice (sembra che ci sia la dimensione della chiave, il numero massimo di indici ecc. Ma forse le mie informazioni sono vecchie)? come funziona con sharding? – log0

2

Redis sarebbe un candidato perfetto per

  • "gli n elementi top" per "milioni di articoli ordinati in base al punteggio"

Redis è dotato di uno struttura di dati che è possibile iniziare da: Sorted Set => ogni membro di un set ordinato è associato al punteggio. Che per esempio possono essere ordinati per punteggio con ZRANGEBYSCORE:

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] 

vi incoraggio a guardare Ordinati Set commands e avere un'idea di Redis, come il vostro problema (come si afferma) chiede. Ovviamente puoi conservare tutti gli attributi che desideri all'interno di un singolo elemento Set.


Per quanto riguarda MongoDB, dal momento che si menzionato milioni di persone, a meno che non si può piegato query incrementali a lavorare per il vostro problema, vorrei non aspettarsi una seconda risposta sub.

Come @nickdos menzionato Solr La pertinenza è una funzionalità abbastanza potente, ma il numero di attributi sarà un problema, poiché sarebbe necessario mantenere tutti questi attributi in memoria per ciascun elemento. Anche se una dozzina per ciascuna potrebbe non essere così male => prova e vedi.

Problemi correlati