2014-10-16 17 views

Odpowiedz

3

Możesz użyć skryptu powłoki Mongo. Zauważ, że wykona pełne skanowanie tabeli.

function findMinMax() { 
     var max = 0; 
     var min = db.collection.findOne().fieldName.length; 

     db.collection.find().forEach(function(doc) { 
      var currentLength = doc.fieldName.length; 
      if (currentLength > max) { 
       max = currentLength; 
      } 
      if (currentLength < min) { 
       min = currentLength; 
      } 
     }); 

     print(max); 
     print(min); 
    } 

    use <databaseName> 
    findMinMax(); 

można zapisać funkcję w pliku c: \ powiedzieć minMax.js i uruchom plik jako

c:\mongodb\bin> mongo dbName < c:\minMax.js 

Uwaga: może trzeba dostarczyć niezbędne hosta, nazwę użytkownika, hasło połączyć się z bazą danych.

c:\mongodb\bin> mongo --host hostName --port portNumber -u userName -p password dbName < c:\minMax.js 
+0

Jak uruchomić to jako skrypt powłoki Mongo? – user3705478

+0

Więc kiedy zapiszę funkcję jako minMax.js, czy powinienem zastąpić db.collection.find(). ForEach (function (doc) {z db. .find(). ForEach (funkcja (doc)? Powinien Podaję tu również nazwę mojej bazy danych use ? – user3705478

5

W nowoczesnych wydaniach MongoDB ma operatorów agregacji $strLenBytes lub $strLenCP niż pozwalają po prostu zrobić:

Class.collection.aggregate([ 
    { "$group" => { 
    "_id" => nil, 
    "max" => { "$max" => { "$strLenCP" => "$a" } }, 
    "min" => { "$min" => { "$strLenCP" => "$a" } } 
    }} 
]) 

Gdzie "a" jest właściwość ciąg w dokumencie chcesz uzyskać min i maksymalna długość od.


Do wyjścia minimalna i maksymalna długość, najlepszym rozwiązaniem jest wykorzystanie dostępnych mapReduce za pomocą kilku sztuczek, aby tylko zachować wartości.

Najpierw trzeba zdefiniować funkcję mapper, który jest po prostu naprawdę będzie wyjście pojedynczy element ze swojej kolekcji, aby zmniejszyć obciążenie:

map = Q%{ 
    function() { 

     if (this.a.length < store[0]) 
     store[0] = this.a.length; 

     if (this.a.length > store[1]) 
     store[1] = this.a.length; 

     if (count == 0) 
     emit(null, 0); 

     count++; 

    } 
} 

Ponieważ pracuje głównie ze zmienną określania zakresów globalnie zachowaniu min i max długości, które chcesz zastąpić w funkcji finalize na emitowanym pojedynczym dokumencie. Nie ma zmniejszyć scenę, ale zdefiniować funkcję „Blank” za to, mimo że nie nazywa się:

reduce = Q%{ function() {} } 

finalize = Q%{ 
    function(key,value) { 
     return { 
      min: store[0], 
      max: store[1] 
     }; 
    } 
} 

następnie wywołać operację mapreduce:

Class.map_reduce(map,reduce).out(inline: 1).finalize(finalize).scope(store: [], count: 0) 

więc cała praca odbywa się na serwer, a nie przez powtarzanie wyników wysyłanych do aplikacji klienckiej. Na małym zestawie tak:

{ "_id" : ObjectId("543e8ee7ddd272814f919472"), "a" : "this" } 
{ "_id" : ObjectId("543e8eedddd272814f919473"), "a" : "something" } 
{ "_id" : ObjectId("543e8ef6ddd272814f919474"), "a" : "other" } 

można uzyskać wynik jak to (wyjście skorupką, lecz tak samo dla kierowcy):

{ 
    "results" : [ 
      { 
        "_id" : null, 
        "value" : { 
          "min" : 4, 
          "max" : 9 
        } 
      } 
    ], 
    "timeMillis" : 1, 
    "counts" : { 
      "input" : 3, 
      "emit" : 1, 
      "reduce" : 0, 
      "output" : 1 
    }, 
    "ok" : 1 
} 

Więc mapreduce umożliwia przetwarzanie JavaScript na serwerze w celu wykonaj to dość szybko, zmniejszając ruch sieciowy. Obecnie nie ma innej natywnej metody, aby MongoDB zwrócił teraz długość łańcucha, więc przetwarzanie JavaScriptu jest konieczne na serwerze.

+0

@muistooshort Dlaczego wyemitowanie 500 000 dokumentów jest bardziej istotne. OP chce tylko wartości min i max. Globalny jest "JavaScript" zadeklarowany i jest rzutowany jako taki. I dostępne tylko dla funkcji mapReduce. Wystarczająco jasne? –

+0

@muistooshort MongoDB nie ma żadnego innego operatora, który zwróci długość łańcucha znaków, więc potrzebujesz JavaScript i mapReduce jest jedynym sposobem na "zwrócenie" wyniku. Mogłoby być lepiej, gdyby istniało coś rodzimego, ale jest to nadal "globalne" porównanie wartości jednego dokumentu z drugą, ponownie, gdzie mapReduce jest jedyną rzeczą, która jest oferowana, aby to zapewnić. Zgniecenie 500 000 dokumentów w reduktorze, aby wykonać pracę, którą można wykonać w programie odwzorowującym, byłoby hackerem i niepotrzebnym, nie mówiąc już o większej ilości pracy. W cytowanym skrypcie JavaScript nie ma wewnętrznych ciągów znaków, więc nie ma to znaczenia. –

Powiązane problemy