2017-07-11 3 views
0

Dies wird von einem Beispiel stammt die bei how to sort array inside collection record in mongoDBSortierung in MongoDB Schal mit einem kundenspezifischen Auftrag

> alit=[{a:16},{a:15},{a:14},{a:13},{a:12},{a:11},{a:10},{a:9},{a:8},{a:7},{a:6},{a:5},{a:4},{a:3},{a:2},{a:1},{a:0}] 
> alit.sort(function(a,b) {return a.a>b.a }) 
[ { "a":8 }, { "a":0 }, { "a":7 }, { "a":14 }, { "a":12 }, { "a":11 }, { "a":10 }, { "a":9 }, { "a":1 }, { "a":13 }, { "a":6 }, { "a":5 }, { "a":4 }, { "a":3 }, { "a":2 }, { "a":15 }, { "a":16 } ] 
> 

Hinweis versehen war, dass, wenn ich diese gleiche Zeile mehr Male ausführen es progressiv mehr und mehr sortiert wird, ist es, als ob Dies führte ein Quicksort aber mit nur zwei Ebenen der Rekursion jedes Mal. Kann mir jemand erklären, was ich falsch mache und wie man eine benutzerdefinierte Reihenfolge definiert, die in einem Rutsch funktioniert?

+1

Wovon redest du? Die Shell ist nur eine einfache JavaScript-REPL und Sie sortieren nur ein einfaches JavaScript-Array mit einem regulären JavaScript ['Array.sort()'] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) -Methode. Funktioniert genau so, wie es sollte und sicherlich nicht, wie Sie behaupten. –

+0

Ich bin in der Lage, die obige Behauptung zu überprüfen. Ich habe deine Aussagen in meine Mongo-Shell kopiert und die Zahlen ein wenig gemischt. Was ich als Ergebnis der Sortierung erhalte, ist das erwartete sortierte Array und nicht das, was du beschreibst. Für was es wert ist, habe ich v3.4.2 verwendet. – ThisClark

+1

Ich benutze v3.0.10 und kopiere buchstäblich meine Zeilen vom Client eingefügt. Ich beanspruche nichts, Neil. –

Antwort

0

Das Problem ist mit der benutzerdefinierten Vergleichsfunktion, die Sie in Ihrer Array-Sortierung verwenden.

Ältere Versionen von JavaScript-Engines (z. B. in der MongoDB 3.0 und früheren Shell) erwarten, dass eine benutzerdefinierte Vergleichsfunktion einen von drei numerischen Werten zurückgibt: positiv (größer als), null (gleich) oder negativ (weniger als). Vergleichsfunktionen, die boolesche Werte zurückgeben, haben undefinierte Ergebnisse (trotz der vernünftigen Erwartung, dass diese zu ihren numerischen Äquivalenten gezwungen werden sollten), so dass das Ergebnis von der JavaScript-Engine abhängt.

Sie sollten das erwartete Ergebnis mit einer Funktion erhalten, die numerische Werte zurückgibt.

Zum Beispiel sollte dies in allen Versionen des mongo Shell arbeiten:

alit.sort(function(a,b) {return a.a - b.a }) 

Hinweis: Um die modernere Motor Spider verwendet in mongo 3.2 oder höher korrekt Sortier Griffe > verwenden, so dass Ihre ursprünglichen Brauch sort() werden Arbeiten Sie wie erwartet in den letzten Versionen der Shell.

+0

Bekam es. Vielen Dank! Es hat wie ein Zauber funktioniert. Ich konnte keine gute Dokumentation finden, wie man den Auftrag definiert oder wie er sich im Laufe der Zeit verändert hat, daher weiß ich die Antwort sehr zu schätzen! –

+0

@ViniBono Das 'Array.sort()' Verhalten liegt innerhalb der JavaScript-Engine und Variationen zwischen Implementierungen sind eine lange Beschwerde (zB: https://stackoverflow.com/questions/3026281/array-sort-sorting-stability-in) -different-browsers, https://www.allenpike.com/2009/arraysort-browser-differenzen/, https://stackoverflow.com/questions/42338978/is-it-really-a-array-sorting-bug- von-Chrom-und-ie). Wenn Sie eine wichtige clientseitige Programmierung oder Manipulation durchführen, wird dies normalerweise besser in einer Treiberimplementierung (z. B. Node.js, Python, ...) als in der 'mongo'-Shell durchgeführt. – Stennie

+1

@ViniBono Informationen zu den JavaScript-Engines, die in den MongoDB-Versionshinweisen verwendet werden, finden Sie in der letzten Änderung ([von V8 zu SpiderMonkey wechseln]) (https://docs.mongodb.com/manual/release-notes/3.2 -javascript /) (Mozillas JS-Engine) in MongoDB 3.2. Die 'mongo'-Shell enthält einen Befehl 'interpreterVersion()', wenn Sie bestätigen möchten, was Ihre Shell verwendet. – Stennie

Verwandte Themen