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

Użycie operatora $slice do pobrania ostatniego elementu tablicy

Jak już wiesz, $slice jest używany tylko w projekcji, aby ograniczyć liczbę elementów tablicy zwracanych w wynikach. Więc utknąłbyś z programowym przetwarzaniem listy z wynikami z find().

Lepszym podejściem jest użycie agregatu. Ale najpierw zastanówmy się, jak $slice jest używany:

> db.collection.find({},{ relevancy: {$slice: -1} })
{ "_id" : ObjectId("530824b95f44eac1068b45c0"), "relevancy" : [  "Y" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c2"), "relevancy" : [  "Y" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c3"), "relevancy" : [  "N" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c4"), "relevancy" : [  "Y" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c6"), "relevancy" : [  "N" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c7"), "relevancy" : [  "N" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c8"), "relevancy" : [  "N" ] }

Otrzymujesz więc ostatni element tablicy, ale utkniesz z zapętleniem wyników, ponieważ nie możesz dopasować ostatnia wartość elementu. Równie dobrze mogłeś to zrobić w kodzie.

Spójrzmy teraz na agregację :

db.collection.aggregate([
    // Match things so we get rid of the documents that will never match, but it will
    // still keep some of course since they are arrays, that *may* contain "N"
    { "$match": { "relevancy": "Y" } },

    // De-normalizes the array
    { "$unwind": "$relevancy" },

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

    // Match only the records with the results you want
    { "$match": { "relevancy": "Y" }},

    // Oh, and maintain the original _id order [ funny thing about $last ]
    { "$sort": { "_id": 1 } }
])

Nawet jeśli byłoby to Twoje pierwsze użycie agregacji(), zachęcam Cię do nauczenia się tego . Jest to prawdopodobnie najbardziej przydatne narzędzie do rozwiązywania problemów. Na pewno był dla mnie. Umieść każdy krok raz na raz, jeśli się uczysz.

Również nie jestem pewien w formularzu dokumentu, wszystkie 1: { ... } Notacja dokumentu podrzędnego wydaje się być błędna, ale powinieneś to wyjaśnić lub dostosować powyższy kod, aby odwoływał się do "1.relevancy" zamiast. Mam jednak nadzieję, że Twoje dokumenty rzeczywiście wyglądają tak:

{ "relevancy" : [  "Y" ] , "_id" : ObjectId("530824b95f44eac1068b45c0") }
{ "relevancy" : [  "Y",  "Y" ] , "_id" : ObjectId("530824b95f44eac1068b45c2") }
{ "relevancy" : [  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c3") }
{ "relevancy" : [  "Y",  "Y" ], "_id" : ObjectId("530824b95f44eac1068b45c4") }
{ "relevancy" : [  "Y",  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c6") }
{ "relevancy" : [  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c7") }
{ "relevancy" : [  "Y",  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c8") }

MongoDB 3.2.x i nowsze

Oczywiście MongoDB 3.2 wprowadza operator „agregacji” dla $slice i jeszcze lepszy $arrayElemAt operator, który eliminuje potrzebę jakiegokolwiek $unwind i $group przetwarzanie. Po początkowym $match zapytanie po prostu tworzysz „logiczne dopasowanie” za pomocą $redact :

db.collection.aggregate([
    { "$match": { "relevancy": "Y" } },
    { "$redact": {
        "$cond": {
            "if": { "$eq": [{ "$arrayElemAt": [ "$relevancy", -1 ], "Y" ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }
    }}   
])

Spowoduje to sprawdzenie ostatniego elementu tablicy podczas podejmowania decyzji, czy $$KEEP lub $$PRUNE dokumenty ze zwróconych wyników.

Jeśli nadal chcesz „projekcja”, możesz dodać $slice :

db.collection.aggregate([
    { "$match": { "relevancy": "Y" } },
    { "$redact": {
        "$cond": {
            "if": { "$eq": [{ "$arrayElemAt": [ "$relevancy", -1 ], "Y" ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }
    }},
    { "$project": { "relevancy": { "$slice": [ "$relevancy", -1 ] } } }
])

Lub alternatywne podejście:

db.collection.aggregate([
    { "$match": { "relevancy": "Y" } },
    { "$project": { "relevancy": { "$slice": [ "$relevancy", -1 ] } } },
    { "$match": { "relevancy": "Y" } }
])

Ale prawdopodobnie mniej kosztowne jest wykonanie $redact najpierw, a następnie „następnie” dokonaj zmiany kształtu w `$project.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Wiosenna sesja z MongoDB

  2. MongoDB $lt Operator potoku agregacji

  3. Jak wyświetlić listę wszystkich baz danych MongoDB w Node.js?

  4. zapytanie sql do mongodb?

  5. Nie można nadpisać modelu po skompilowaniu Mongoose