MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Sortowanie MongoDB a sortowanie zagregowane $sortowanie według indeksu tablicy

Struktura agregacji po prostu nie „obsługuje” tablic w taki sam sposób, jak w przypadku .find() zapytania w ogóle. Dotyczy to nie tylko operacji takich jak .sort() , ale także z innymi operatorami, a mianowicie $slice , chociaż ten przykład zostanie naprawiony (więcej później).

Tak więc jest prawie niemożliwe, aby poradzić sobie z czymkolwiek za pomocą formy "notacji kropkowej" z indeksem pozycji tablicy, tak jak masz. Ale jest na to sposób.

To, co „możesz” zrobić, to po prostu ustalić, czym właściwie jest „n-ty” element tablicy jako wartość, a następnie zwrócić go jako pole, które można posortować:

  db.test.aggregate([
    { "$unwind": "$items" },
    { "$group": { 
      "_id": "$_id",
      "items": { "$push": "$items" },
      "itemsCopy":  { "$push": "$items" },
      "first": { "$first": "$items" }
    }},
    { "$unwind": "$itemsCopy" },
    { "$project": {
      "items": 1,
      "itemsCopy": 1,
      "first": 1,
      "seen": { "$eq": [ "$itemsCopy", "$first" ] }
    }},
    { "$match": { "seen": false } },
    { "$group": {
      "_id": "$_id",
      "items": { "$first": "$items" },
      "itemsCopy": { "$push": "$itemsCopy" },
      "first": { "$first": "$first" },
      "second": { "$first": "$itemsCopy" }
    }},
    { "$sort": { "second": -1 } }
  ])

Jest to okropne i „iterowalne” podejście, w którym zasadniczo „przechodzisz” przez każdy element tablicy, pobierając $first dopasowanie według dokumentu z tablicy po przetworzeniu za pomocą $ odpręż się . Następnie po $unwind ponownie, sprawdzasz, czy te elementy tablicy są takie same jak te, które już „widziano” w zidentyfikowanych pozycjach tablicy.

To straszne i gorzej dla większej liczby pozycji, którymi chcesz się poruszać, ale daje wynik:

{ "_id" : 2, "items" : [ 0, 3, 4 ], "itemsCopy" : [ 3, 4 ], "first" : 0, "second" : 3 }
{ "_id" : 1, "items" : [ 1, 2, 0 ], "itemsCopy" : [ 2, 0 ], "first" : 1, "second" : 2 }
{ "_id" : 3, "items" : [ 2, 1, 5 ], "itemsCopy" : [ 1, 5 ], "first" : 2, "second" : 1 }

Na szczęście nadchodzące wydania MongoDB (takie jak obecnie dostępne w wydaniach deweloperskich) otrzymują "poprawkę" na to. Może nie jest to „idealna” poprawka, której pragniesz, ale rozwiązuje podstawowy problem.

Jest nowy $slice operator dostępny dla struktury agregacji tam i zwróci wymagane elementy tablicy z indeksowanych pozycji:

  db.test.aggregate([
    { "$project": {
      "items": 1,
      "slice": { "$slice": [ "$items",1,1 ] }
    }},
    { "$sort": { "slice": -1 } }
  ])

Co daje:

{ "_id" : 2, "items" : [ 0, 3, 4 ], "slice" : [ 3 ] }
{ "_id" : 1, "items" : [ 1, 2, 0 ], "slice" : [ 2 ] }
{ "_id" : 3, "items" : [ 2, 1, 5 ], "slice" : [ 1 ] }

Możesz więc zauważyć, że jako „plaster” wynik nadal jest „tablicą”, jednak $sort w ramach agregacji zawsze używał „pierwszej pozycji” tablicy w celu posortowania zawartości. Oznacza to, że przy pojedynczej wartości wyodrębnionej z indeksowanej pozycji (tak jak w długiej procedurze powyżej) wynik zostanie posortowany zgodnie z oczekiwaniami.

Końcowe przypadki tutaj są takie, jak to działa. Albo żyć z takimi operacjami, jakich potrzebujesz z góry, aby pracować z indeksowaną pozycją tablicy, albo „poczekać”, aż nowa błyszcząca wersja przyjdzie ci na ratunek z lepszymi operatorami.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Do serwera MongoDB nadal można uzyskać dostęp bez poświadczeń

  2. mongodb/mongoose findMany - znajdź wszystkie dokumenty z identyfikatorami wymienionymi w tablicy

  3. Kiedy dokument został dodany do kolekcji MongoDB?

  4. W Jongo, jak znaleźć wiele dokumentów z Mongodb według listy identyfikatorów?

  5. MongoDB - Agregacja - Aby uzyskać unikalne elementy w tablicy