2012-04-30 7 views
5

Ich habe Millionen von Elementen, die nach einem vorberechneten Wert sortiert sind. Jedes Element hat viele boolesche Attribute. Lassen Sie uns sagen, dass es etwa zehntausend mögliche Attribute gibt, von denen jedes ein Dutzend hat.Datenspeicherlösung für die Tag-Suche

Ich würde gerne in der Lage in Echtzeit (einige Millisekunden) die oberen n Elemente gegeben ~ eine beliebige Kombination von Attributen.

Welche Lösung würden Sie empfehlen? Ich suche nach etwas extrem Skalierbarem.

-
- Wir suchen bei mongodb und Array-Index, sehen Sie eine Beschränkung?
- SolR ist eine mögliche Lösung, aber wir brauchen keine Textsuchfunktionen.

+1

Wenn Sie "nach Punktzahl" sagen, meinst du, das ist bereits vorberechnet? Wenn dies der Fall ist, kann SOLR keinen Vorteil bringen. Wenn nicht, bietet SOLR eine sehr mächtige und anpassbare Relevanzrangfolge. – nickdos

+0

Millionen von Items sind für SOLR kein Problem, aber 10.000 mögliche Attribute könnten ein Problem sein. SOLR unterstützt dynamische Felder, so dass Sie nicht alle Attribute definieren müssen, aber Speicher mit einem breiten/spärlichen Schema platzen kann. Andere können dazu besser beraten. – nickdos

+0

@nickdos ja das Ergebnis ist vorberechnet. Und ich denke, Sie haben Recht, der schwierige Teil ist die große Anzahl von Attributen. Ich weiß nicht, wie mongodb damit umgeht. Erstellt es einen Index pro Attribute? Ist es sogar möglich, so viele Indizes zu haben? Wir werden trotzdem testen, aber ich möchte sicher sein, dass wir die richtige Strategie nicht verpassen. – log0

Antwort

9

MongoDB verarbeiten kann, was Sie wollen, wenn Sie diese Ihre Objekte wie gespeichert

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

Dann wird die folgende Abfrage alle Einzelteile wird übereinstimmen, die att1 und attr2

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

aber gewonnen‘haben t es übereinstimmen

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

die Abfrage gibt einen Cursor zurück, wenn Sie möchten, dass dieser Cursor sortiert wird, t hen nur die Sortierparameter auf die Abfrage hinzufügen, wie so

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

einen Blick auf Advanced Queries haben, um zu sehen, was möglich ist.

Geeignete Indizes können so eingestellt werden, wie

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

folgt Und Sie können Performance-Informationen mit

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

Mongo erklärt, wie viele Objekte wurden gescannt, wie lange der Betrieb nahm und verschiedene andere Statistiken erhalten .

+0

In der Tat scheint Mongodb dem Bedürfnis sehr gut zu entsprechen, aber ich mache mir Sorgen um die Effizienz. Sie haben hier keine Indizes erwähnt. Ist ein Index für Attribute und Punkte in meinem Fall genug ... – log0

+0

Ich habe Informationen über Indizes hinzugefügt. Stellen Sie sicher, dass alle Ihre Indizes in den Speicher passen, andernfalls werden Ihre Abfragen langsam. –

+0

Ich habe irgendwo gelesen, dass es maximal 64 Indizes für eine Sammlung geben kann. Was passiert bei einem indizierten Array? Bedeutet das, dass Mongo 10 000 Indizes erstellen wird? – log0

2

Genau damit kann Mongo umgehen. Die Tatsache, dass Ihre Attribute boolesch sind, hilft hier. Ein mögliches Schema ist unten aufgeführt:

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

Dann können wir Index auf true_tags und false_tags. Und es sollte effizient sein, mit $ in, $ all, ... Query Operatoren zu suchen.

+0

Sorry, es war nicht sehr klar, aber mit boolean ich meinte, entweder das Element hat das Attribut entweder nicht. Deine Antwort steht immer noch, aber ich suche nach genaueren Informationen. Gibt es eine Beschränkung für diese Art von Index (scheint, dass es auf Schlüsselgröße, maximale Anzahl von Index etc .. aber vielleicht meine Informationen sind alt)? Wie funktioniert es mit Sharding? – log0

2

Redis wäre ein perfekter Kandidat für

  • „die Top-n-Produkte“ für „Millionen von Artikeln nach Punkten geordnet“ sein

Redis hat in der Datenstruktur einen eingebauten, den Sie mit start von: Sorted Set => jedes Mitglied eines Sorted Set ist mit Score verbunden. Die beispielsweise nach Punkten mit ZRANGEBYSCORE gewählt werden:

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

ich Sie ermutigen, bei Sorted Set commands zu sehen und ein Gefühl für Redis, wie Ihr Problem erhalten (wie es heißt) fordert sie. Sie können natürlich beliebig viele Attribute innerhalb eines einzelnen Set-Elements beibehalten.


Soweit MongoDB, da Sie Millionen erwähnt, es sei denn, Sie inkrementelle Abfragen gebogen sind, können für Ihr Problem zu arbeiten, würde ich kein Unter zweite Antwort erwarten.

Als @nickdos erwähnt Solr Relevancy ist eine ziemlich mächtige Funktion, aber die Anzahl der Attribute wird ein Problem sein, da es alle diese Attribute im Speicher für jedes Element gespeichert werden müssen. Obwohl ein Dutzend für jeden nicht so schlecht sein kann => versuche es einfach.