2013-04-17 7 views
5

Ich habe diese Elemente in meiner MongoDB Sammlung:Distinct() Befehl mit Skip() verwendet und limit()

{x: 1, y: 60, z:100} 
{x: 1, y: 60, z:100} 
{x: 1, y: 60, z:100} 
{x: 2, y: 60, z:100} 
{x: 2, y: 60, z:100} 
{x: 3, y: 60, z:100} 
{x: 4, y: 60, z:100} 
{x: 4, y: 60, z:100} 
{x: 5, y: 60, z:100} 
{x: 6, y: 60, z:100} 
{x: 6, y: 60, z:100} 
{x: 6, y: 60, z:100} 
{x: 7, y: 60, z:100} 
{x: 7, y: 60, z:100} 

Ich mag die unterschiedlichen Werte von x abzufragen (dh [1, 2, 3 , 4, 5, 6, 7]) ... aber ich möchte nur einen Teil von ihnen (ähnlich dem, was wir mit skip (a) und limit (b) erreichen können).

Wie mache ich das mit dem Java-Treiber von MongoDB (oder mit Feder-Daten-Mongodb, wenn möglich)?

Antwort

8

in Mongo Shell ist einfach mit Aggregat Rahmen:

db.collection.aggregate([{$group:{_id:'$x'}}, {$skip:3}, {$limit:5}]) 

für Java-Look: use aggregation framework in java

1

Je nach Anwendungsfall, Sie finden diese Vorgehensweise kann performanter als Aggregation zu sein. Hier ist eine Mongo Shell Beispielfunktion.

function getDistinctValues(skip, limit) { 

    var q = {x:{$gt: MinKey()}}; // query 
    var s = {x:1};    // sort key 

    var results = []; 

    for(var i = 0; i < skip; i++) { 
     var result = db.test.find(q).limit(1).sort(s).toArray()[0]; 
     if(!result) { 
      return results; 
     } 
     q.x.$gt = result.x; 
    } 

    for(var i = 0; i < limit; i++) { 
     var result = db.test.find(q).limit(1).sort(s).toArray()[0]; 
     if(!result) { 
      break; 
     } 
     results.push(result.x); 
     q.x.$gt = result.x; 
    } 

    return results; 

} 

finden wir im Grunde nur die eine Wert in einer Zeit, die Abfrage und sortieren letzte Werte, die wir gesehen haben, schon zu überspringen. Sie können dies leicht verbessern, indem Sie weitere Argumente hinzufügen, um die Funktion flexibler zu machen. Wenn Sie einen Index für die Eigenschaft erstellen, für die Sie unterschiedliche Werte suchen möchten, wird die Leistung ebenfalls verbessert.

Eine weniger offensichtliche Verbesserung wäre, die Phase "skip" alle zusammen zu überspringen und einen Wert anzugeben, von dem aus fortgefahren werden kann. Hier ist eine Mongo Shell Beispielfunktion.

function getDistinctValues(limit, lastValue) { 

    var q = {x:{$gt: lastValue === undefined ? MinKey() : lastValue}}; // query 
    var s = {x:1};    // sort key 

    var results = []; 

    for(var i = 0; i < limit; i++) { 
     var result = db.test.find(q).limit(1).sort(s).toArray()[0]; 
     if(!result) { 
      break; 
     } 
     results.push(result.x); 
     q.x.$gt = result.x; 
    } 

    return results; 

} 

Wenn Sie mit der Aggregation Technik gehen entscheiden, stellen Sie sicher, dass Sie eine $ Sortierstufe nach der Gruppenphase $ hinzufügen. Andernfalls werden Ihre Ergebnisse nicht in einer vorhersehbaren Reihenfolge angezeigt.

+0

Dies ist schlecht im Fall der Leistung. Anstelle von 1 Aggregationsanforderung senden Sie Limit-Anfragen an die Datenbank. – Rayz