sql >> Database teknologi >  >> NoSQL >> MongoDB

mongodb-forespørgsel:$size med $gt returnerer altid 0

Du kan ikke gøre det, som der faktisk henvises til i dokumentationen til $size . Så denne operatør alene evaluerer et "bogstaveligt" resultat og kan ikke bruges sammen med "områdeoperatorer", som du spørger om.

Dine eneste rigtige muligheder er at bede om en "størrelse", der er "ikke lig med 0" ved at negere betingelsen med $not operatør. Hvilket er helt gyldigt:

db.userStats.count({ "sessions": { "$not": { "$size": 0 } } });

Eller på anden måde test med den anden inkarnation af $size i aggregeringsrammen, så længe din MongoDB-version er 2.6 eller nyere:

db.userStats.aggregate([
    { "$group": {
         "_id": null,
         "count": {
             "$sum": {
                 "$cond": [
                     { "$gt": [ { "$size": "$sessions", 0 } ] },
                     1,
                     0
                 ]
             }
         }
    }}
])

Muligvis også med $where form for JavaScript-evaluering:

db.userStats.count(function() { return this.sessions.length > 0 });

Men sandsynligvis langsommere end den sidste version.

Eller faktisk kan du bare gøre dette med "dot notation" , og $exists operatør:

db.userStats.count({ "sesssions.0": { "$exists": true } });

Som den generelle idé er, at hvis der er et element ved indekset 0 så har arrayet en vis længde.

Det hele afhænger af din tilgang, men enhver af disse former får det rigtige resultat.

Men for den "bedste" ydeevne fra MongoDB, brug ikke nogle af disse metoder. Behold i stedet arrayet "længde" som en egenskab for det dokument, du inspicerer. Dette kan du "indeksere", og de udsendte forespørgsler kan faktisk få adgang til det indeks, hvilket ingen af ​​ovenstående kan gøre.

Hold det sådan her:

db.userStats.update(
     { "_id": docId, "sessions": { "$ne": newItem } },
     {
         "$push": { "sessions": newItem },
         "$inc": { "countSessions": 1 }
     }
)

Eller for at fjerne:

db.userStats.update(
     { "_id": docId, "sessions": newItem  },
     {
         "$pull": { "sessions": newItem },
         "$inc": { "countSessions": -1 }
     }
)

Så kan du bare forespørge på "countSesssions", som også kan indeksere for den bedste ydeevne:

db.userStats.find({ "countSessions": { "$gt": 0 } })

Og det er den "bedste" måde at gøre det på.



  1. Hvad er HBase Compactions?

  2. Implementering af Meteor App til egen server

  3. Hvad sker der med Meteor og Fibres/bindEnvironment()?

  4. Afkodning af MongoDB fejllogfiler