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

Jak znaleźć w mongodb do ostatniego elementu tablicy?

Wiem, że to pytanie jest stare, ale znalazłem je w Google po udzieleniu odpowiedzi na podobne nowe pytanie . Więc pomyślałem, że zasługuje to na takie samo traktowanie.

Możesz uniknąć spadku wydajności $where za pomocą agregacji zamiast tego:

db.example.aggregate([

    // Use an index, which $where cannot to narrow down
    {$match: { "comments.by": "Abe" }},

    // De-normalize the Array
    {$unwind: "$comments"},

    // The order of the array is maintained, so just look for the $last by _id
    {$group: { _id: "$_id", comments: {$last: "$comment"} }},

    // Match only where that $last comment by `by.Abe`
    {$match: { "comments.by": "Abe" }},

    // Retain the original _id order
    {$sort: { _id: 1 }}

])

I to powinno krążyć wokół $gdzie ponieważ udało nam się zawęzić dokumenty, które miały komentarz "Abe" w pierwszej kolejności. Zgodnie z ostrzeżeniem, $gdzie przetestuje każdy dokument w kolekcji i nigdy nie użyje indeksu, nawet jeśli taki istnieje.

Oczywiście możesz również zachować oryginalny dokument, korzystając z techniki opisanej tutaj również, więc wszystko działałoby jak find() .

Tylko do myślenia dla każdego, kto to znajdzie.

Aktualizacja dla nowoczesnych wydań MongoDB

Nowoczesne wersje dodały $redact wyrażenie potoku, a także $arrayElemAt (ta ostatnia od 3.2, więc byłaby to minimalna wersja tutaj), która w połączeniu pozwoliłaby wyrażeniu logicznemu na sprawdzenie ostatniego elementu tablicy bez przetwarzania $unwind etap:

db.example.aggregate([
  { "$match": { "comments.by": "Abe" }},
  { "$redact": {
    "$cond": {
      "if": {
        "$eq": [
          { "$arrayElemAt": [ "$comments.by", -1 ] },
          "Abe"
        ]
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

Logika jest tutaj wykonana w porównaniu z $arrayElemAt pobiera ostatni indeks tablicy -1 , który jest przekształcany w tablicę wartości w "by" właściwość za pośrednictwem $map . Pozwala to na porównanie pojedynczej wartości z wymaganym parametrem "Abe" .

Lub nawet nieco bardziej nowoczesny przy użyciu $expr dla MongoDB 3.6 i nowszych:

db.example.find({
  "comments.by": "Abe",
  "$expr": {
    "$eq": [
      { "$arrayElemAt": [ "$comments.by", -1 ] },
      "Abe"
    ]
  }
})

Byłoby to zdecydowanie najbardziej wydajne rozwiązanie do dopasowywania ostatniego elementu w tablicy i faktycznie powinno zastąpić użycie $where w większości przypadków, a zwłaszcza tutaj.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Jak mogę dodać obrazy w mongoDB?

  2. Jak zaktualizować zagnieżdżoną tablicę?

  3. MongoDB — struktura agregacji (łączna liczba)

  4. Pomieszanie dwóch równoczesnych żądań w aplikacji Node.js

  5. Yii Emongodocuments w pobliżu zapytań ignorujących maxDistance