2014-07-21 12 views
9

Ricerca di testo completo in Cassandra;Ricerca completa di testo di Cassandra

Sono abbastanza nuovo per Cassandra e desidero capirlo più correttamente. Sto tentando di eseguire una ricerca full-text in Cassandra, ma dopo alcune ricerche ho trovato che ci non può essere un approccio "semplice" per questo .. e dico forse perché la prima pagina di Google non ha detto molto di nulla.

Quindi sto cercando di capire ora, invece, qual è l'approccio migliore qui .. Questo tipo di mi porta a prendere in mano le mie ipotesi basate su ciò che ho imparato finora su Cassandra, che si basa su questi due principi; a) progetta le tue tabelle in base alle tue query, piuttosto che ai dati, e b) more-data è una buona cosa, a patto che venga utilizzata correttamente.

Con ciò detto, ho trovato un paio di soluzioni che mi piacerebbe condividere, e chiedo anche che se qualcuno ha un'idea migliore, per favore riempimi su di esso prima di impegnarmi in qualcosa di irragionevole/ingenuo .

prima soluzione: creare una famiglia Colonna (CF), con due chiavi primarie e di un indice in questo modo:

CREATE TABLE "FullTextSearch" (
"PartialText" text, 
"TargetIdentifier" uuid, 
"CompleteText" text, 
"Type" int, 
PRIMARY KEY ("PartialText","TargetIdentifier") 
); 
CREATE INDEX IX_FullTextSearch_Type "keyspace"."FullTextSearch" ("Type"); 

Con la tabella di cui sopra, avrei bisogno di inserire righe per il testo "Ciao Mondo" come segue:

BATCH APPLY; 
INSERT INTO "FullTextSearch" ("PartialText","TargetIdentifier","CompleteText","Type") VALUES ("H",000000000-0000-0000-0000-000000000,"Hello World",1); 
INSERT INTO "FullTextSearch" ("PartialText","TargetIdentifier","CompleteText","Type") VALUES ("He",000000000-0000-0000-0000-000000000,"Hello World",1); 
INSERT INTO "FullTextSearch" ("PartialText","TargetIdentifier","CompleteText","Type") VALUES ("Hel",000000000-0000-0000-0000-000000000,"Hello World",1); 
..... 
INSERT INTO "FullTextSearch" ("PartialText","TargetIdentifier","CompleteText","Type") VALUES ("Hello Wor",000000000-0000-0000-0000-000000000,"Hello World",1); 
INSERT INTO "FullTextSearch" ("PartialText","TargetIdentifier","CompleteText","Type") VALUES ("Hello Worl",000000000-0000-0000-0000-000000000,"Hello World",1); 
INSERT INTO "FullTextSearch" ("PartialText","TargetIdentifier","CompleteText","Type") VALUES ("Hello World",000000000-0000-0000-0000-000000000,"Hello World",1); 
..... 
INSERT INTO "FullTextSearch" ("PartialText","TargetIdentifier","CompleteText","Type") VALUES ("Wor",000000000-0000-0000-0000-000000000,"Hello World",1); 
INSERT INTO "FullTextSearch" ("PartialText","TargetIdentifier","CompleteText","Type") VALUES ("Worl",000000000-0000-0000-0000-000000000,"Hello World",1); 
INSERT INTO "FullTextSearch" ("PartialText","TargetIdentifier","CompleteText","Type") VALUES ("World",000000000-0000-0000-0000-000000000,"Hello World",1); 
END BATCH; 

Fondamentalmente, quanto sopra vi soddisfare la seguente jolly/partialtext "% o W%", "Ciao%", "Worl%"; Tuttavia non soddisfa parole parziali come "% ell%" per "Ciao", che posso sentire ok circa per ora ..... (OCD sorta calci qui)

Questo tipo di approccio fa schifo per me perché ora dovrei eliminare/reinserire ogni volta che si verifica una modifica di salvataggio/nome sul "TargetIdentifier";

La seconda soluzione, sarebbe molto simile solo questa volta facendo uso di colonne larghe; dove il tavolo potrebbe essere simile:

CREATE TABLE "FullTextSearch" (
"TargetIdentifier" uuid, 
"Type" int, 
"CompleteText" text, 
PRIMARY KEY("TargetIdentifier") 
); 

e ora nel corso di un qualcosa di ricerca come:

SELECT * FROM "FullTextSearch" WHERE "He" = 1; 

in modo che se esiste la colonna, le rispettive righe vengono restituite;

Terza Soluzione: simile a quello sopra, ma questa volta invece di utilizzare ampie colonne usiamo una colonna insieme come programma per i testi parziali, ed eseguire una query come:

SELECT * FROM "FullTextSearch" WHERE "PartialTexts"['He'] = 1; 

Comunque , Sono tutto fuori di idee, è tardi, e posso solo sperare in una grande risposta! Per favore, fammi sapere cosa dovrei fare qui ... Sono sulla buona strada?

risposta

6

AFAIK Datastax Enterprise Search è il successore (commerciale) di Solandra.

Cassandra 2.0 supporta i cosiddetti "indici secondari personalizzati". Gli indici secondari personalizzati sono codice Java. La tua implementazione deve implementare la classe astratta (Vedi http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/create_index_r.html)

Non sono sicuro che esistano implementazioni per Elasicsearch o Solr.

Non consiglierei di codificare tutte le strane logiche di ricerca full-text come la derivazione, il supporto di lingue multiple/esotiche o anche roba geo spaziale.

Ma SecondaryIndex sarebbe un buon punto per iniziare a integrare il tuo motore di ricerca preferito.

0

Partenza SOLANDRA (ex Lucandra)

Ma penso Solandra Non è attivamente sviluppato più, l'autore si trasferisce a Datastax e continuò il suo lavoro lì.

Così si può anche dare un'occhiata al Datastax Enterprise Search

Ci sono alcune limitazioni anche, guarda DistributedSearch

0

La cosa molto di base su Cassandra è se si desidera utilizzare clausola where per la filtrazione di record quella colonna è o chiave primaria o devi assegnargli un indice, quindi quello che posso vedere è che hai dato la chiave primaria al campo "TargetIdentifier" e indicizzazione a "Tipo" e usando "CompleteText" nella clausola where così potrebbe non funzionare ..

Assegnare l'indice secondario a "CompleteTex" e verificare se si stai ottenendo l'output desiderato o meno.

1

Se il set di dati è relativamente piccolo, è sufficiente utilizzare un'istanza in memoria di lucene, aggiornare l'indice a intervalli regolari e si è pronti per andare.

0

Un altro paio di opzioni disponibili: Stratio Lucene Plugin. Questo utilizza Lucene per implementare un indice secondario nativo.

È inoltre disponibile SSTable Attached Secondary Index (SASI) da utilizzare per la ricerca di testo.

Sappi che entrambe queste strategie utilizzano indici distribuiti localmente tali che le query non saranno molto performanti poiché le ricerche finiranno per essere trasmesse attraverso l'intero cluster. Per SASI, è possibile evitare questo se è possibile utilizzare una chiave di partizione come parte della query.

Problemi correlati