sql >> Database >  >> NoSQL >> MongoDB

Query op laatste arraywaarde

Het belangrijkste hier is de aggregatie $slice om het laatste element uit de array te halen,

db.chat.aggregate([
 { "$match": { "user1": 1,  "messages.capty": "B" } },
 { "$redact": {
   "$cond": {
     "if": { 
       "$eq": [ { "$slice": [ "$messages.capty", -1 ] }, ["B"] ]  
     },
     "then": "$$KEEP",
     "else": "$$PRUNE"
   }
 }},
 { "$project": {
   "user2": 1,
   "body": {
     "$arrayElemAt": [
       { "$map": {
         "input": { 
           "$filter": {
             "input": { "$slice": [ "$messages",-1 ] },
             "as": "m",
             "cond": { "$eq": [ "$$m.capty", "B" ] }
           }
         },
         "as": "m",
         "in": "$$m.body"
       }},
       0
     ]
   }
 }}
])

Ik ben eigenlijk "extra veilig" in het $project stage met de $filter maar het is eigenlijk allemaal hetzelfde.

Eerst selecteert de query de documenten, we kunnen op dit moment niet zeggen dat ze "alleen" overeenkomen met het laatste element van de array, maar we willen documenten filteren die de voorwaarde helemaal niet in de array hebben.

De $redact is het eigenlijke ding dat naar het "laatste" array-item kijkt en de waarde van het veld test. We kunnen alleen het veld uit de array noteren met $messages.capty die slechts een array van die items retourneert. Hier hebben we dan $slice of zelfs $arrayElemAt als je de laatste waarde wilt krijgen, zijnde de index van -1 .

Op dit punt hebben we alleen de "documenten" "gefilterd" die niet overeenkomen met de voorwaarde. De laatste $project stage neemt het laatste element van de array, controleert of het overeenkomt met de voorwaarde (wat het zou moeten doen door de eerdere fasen), extraheert de waarde van "body" en verandert de enkele array-inhoud in alleen de gewone waarde.

Je kunt ook afzien van de "voorzichtigheid" en gewoon het laatste array-element pakken sinds $redact had zijn werk moeten doen:

db.chat.aggregate([
 { "$match": { "user1": 1,  "messages.capty": "B" } },
 { "$redact": {
   "$cond": {
     "if": { 
       "$eq": [ { "$arrayElemAt": [ "$messages.capty", -1 ] }, "B" ]  
     },
     "then": "$$KEEP",
     "else": "$$PRUNE"
   }
 }},
 { "$project": {
   "user2": 1,
   "body": {
     "$arrayElemAt": [ "$messages.body", -1 ]
   }
 }}
])

Het hele ding valt echt uiteen om "te matchen met de mogelijke documenten met een query" en vervolgens "vergelijk en extraheer het laatste element met $slice of $arrayElemAt ".

Resultaten zijn:

{
        "_id" : ObjectId("593921425ccc8150f35e7663"),
        "user2" : 3,
        "body" : "hiii 23"
}
{
        "_id" : ObjectId("593921425ccc8150f35e7664"),
        "user2" : 4,
        "body" : "hiii 24"
}



  1. Spring boot probeert verbinding te maken met mongo bij het toevoegen van mongo-java-driver maven-afhankelijkheid

  2. Meertalige gegevensmodellering op MongoDB

  3. Afronding op 2 decimalen met behulp van het MongoDB-aggregatieraamwerk

  4. MongoDB hoofdletterongevoelige sleutel zoeken