sql >> Database >  >> NoSQL >> MongoDB

Lengte stringveldwaarde in mongoDB

Voor MongoDB 3.6 en nieuwer:

De $expr operator staat het gebruik van aggregatie-expressies binnen de querytaal toe, dus u kunt gebruikmaken van het gebruik van $strLenCP operator om de lengte van de string als volgt te controleren:

db.usercollection.find({ 
    "name": { "$exists": true },
    "$expr": { "$gt": [ { "$strLenCP": "$name" }, 40 ] } 
})

Voor MongoDB 3.4 en nieuwer:

U kunt het aggregatieraamwerk ook gebruiken met de $redact pijplijnoperator waarmee u de logische voorwaarde kunt verwerken met de $cond operator en gebruikt de speciale bewerkingen $$KEEP om het document te "bewaren" waar de logische voorwaarde waar is of $$PRUNE om het document te "verwijderen" waarin de voorwaarde onwaar was.

Deze bewerking is vergelijkbaar met het hebben van een $project pijplijn die de velden in de verzameling selecteert en een nieuw veld maakt dat het resultaat van de logische voorwaardequery bevat en vervolgens een daaropvolgende $match , behalve dat $redact gebruikt een enkele pijplijnfase die efficiënter is.

Wat betreft de logische voorwaarde, er zijn String Aggregation Operators die u kunt gebruiken $strLenCP operator om de lengte van de string te controleren. Als de lengte $gt . is een opgegeven waarde, dan is dit een echte overeenkomst en wordt het document "bewaard". Anders wordt het "gesnoeid" en weggegooid.

Overweeg de volgende aggregatiebewerking uit te voeren die het bovenstaande concept demonstreert:

db.usercollection.aggregate([
    { "$match": { "name": { "$exists": true } } },
    {
        "$redact": {
            "$cond": [
                { "$gt": [ { "$strLenCP": "$name" }, 40] },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    },
    { "$limit": 2 }
])

Bij gebruik van $where , probeer uw zoekopdracht zonder de tussenhaken:

db.usercollection.find({$where: "this.name.length > 40"}).limit(2);

Een betere vraag zou zijn om te controleren op het bestaan ​​van het veld en vervolgens de lengte te controleren:

db.usercollection.find({name: {$type: 2}, $where: "this.name.length > 40"}).limit(2); 

of:

db.usercollection.find({name: {$exists: true}, $where: "this.name.length > 
40"}).limit(2); 

MongoDB evalueert niet-$where querybewerkingen vóór $where uitdrukkingen en niet-$where query-instructies kunnen een index gebruiken. Een veel betere prestatie is om de lengte van de string op te slaan als een ander veld en dan kunt u erop indexeren of zoeken; $where toepassen zal veel langzamer zijn in vergelijking met dat. Het wordt aanbevolen om JavaScript-expressies te gebruiken en de $where operator als laatste redmiddel wanneer u de gegevens niet op een andere manier kunt structureren, of wanneer u te maken heeft met een kleine subset van gegevens.

Een andere en snellere aanpak die het gebruik van de $where . vermijdt operator is de $regex exploitant. Beschouw het volgende patroon dat zoekt naar

db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2); 

Opmerking - Uit de documenten :

Als er een index voor het veld bestaat, vergelijkt MongoDB de reguliere expressie met de waarden in de index, wat sneller kan zijn dan een verzamelingsscan. Verdere optimalisatie kan plaatsvinden als de reguliere expressie een "prefixexpressie" is, wat betekent dat alle potentiële overeenkomsten met dezelfde tekenreeks beginnen. Hierdoor kan MongoDB een "bereik" maken van dat voorvoegsel en alleen overeenkomen met die waarden uit de index die binnen dat bereik vallen.

Een reguliere expressie is een “prefixexpressie” als deze begint met acaret (^) of een linker anker (\A) , gevolgd door een reeks eenvoudige symbolen. Bijvoorbeeld de regex /^abc.*/ wordt geoptimaliseerd door alleen te matchen met de waarden uit de index die beginnen met abc .

Bovendien, terwijl /^a/, /^a.*/, en /^a.*$/ overeenkomen met equivalentstrings, hebben ze verschillende prestatiekenmerken. Al deze uitdrukkingen gebruiken een index als er een geschikte index bestaat; echter,/^a.*/ , en /^a.*$/ zijn langzamer. /^a/ kan stoppen met scannen nadat het voorvoegsel overeenkomt.



  1. MongoDB installeren met Homebrew

  2. Transacties in MongoDB

  3. Verschil tussen MongoDB en Mongoose

  4. Map/reduce gebruiken om de eigenschappen in een collectie in kaart te brengen