sql >> Databasteknik >  >> NoSQL >> MongoDB

Fråga om sista matrisvärde

Huvudsaken här är aggregeringen $slice för att hämta det sista elementet från arrayen,

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
     ]
   }
 }}
])

Jag är faktiskt "extra säker" i $project steg med $filter men allt är i princip likadant.

Först väljer frågan dokumenten, vi kan faktiskt inte säga att vi "bara" matchar det sista elementet i arrayen, men vi vill filtrera dokument som inte har villkoret på arrayen alls.

$redact är den faktiska sak som tittar på den "sista" array-posten och testar värdet på fältet. Vi kan bara notera fältet från arrayen med $messages.capty som bara returnerar en mängd av dessa föremål. Här har vi sedan $slice eller till och med $arrayElemAt om du vill få det sista värdet, som är indexet för -1 .

Vid det här laget "filtrerade" vi bara de "dokument" som inte matchar villkoret. Det sista $project stage tar det sista elementet i arrayen, kontrollerar att det matchar villkoret (vilket det borde i de tidigare stegen), extraherar värdet på "body" och förvandlar innehållet i en array till bara det vanliga värdet.

Du kan alternativt avstå från "försiktighet" och helt enkelt bara ta det sista arrayelementet sedan $redact borde ha gjort sitt jobb:

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 ]
   }
 }}
])

Det hela går verkligen sönder för att "matcha det möjliga dokument med en fråga" och sedan "jämför och extrahera det sista elementet med $slice eller $arrayElemAt ".

Resultaten är:

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



  1. Hantera Mongoose Populated Fields i GraphQL

  2. Spring repository autocast-enheter med olika klasstyper

  3. MongoDB Collection Structure Performance

  4. Nod MongoDb { err:'anslutning till [127.0.0.1:27017] tog timeout' }