sql >> Databáze >  >> NoSQL >> MongoDB

Délka hodnoty pole řetězce v mongoDB

Pro MongoDB 3.6 a novější:

$expr operátor umožňuje použití agregačních výrazů v rámci dotazovacího jazyka, takže můžete využít použití $strLenCP operátor pro kontrolu délky řetězce následovně:

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

Pro MongoDB 3.4 a novější:

Můžete také použít agregační rámec s $redact operátor potrubí, který vám umožňuje zpracovat logickou podmínku pomocí $cond operátor a používá speciální operace $$KEEP "uchovat" dokument, kde je logická podmínka pravdivá nebo $$PRUNE k "odstranění" dokumentu, kde byla podmínka nepravdivá.

Tato operace je podobná jako u $project kanál, který vybere pole v kolekci a vytvoří nové pole, které obsahuje výsledek z dotazu na logickou podmínku a poté následný $match , kromě $redact používá jeden stupeň potrubí, který je efektivnější.

Pokud jde o logickou podmínku, existují operátory agregace řetězců, které můžete použít $strLenCP operátor pro kontrolu délky řetězce. Pokud je délka $gt zadanou hodnotu, pak se jedná o skutečnou shodu a dokument je „uchován“. V opačném případě je "prořezán" a zahozen.

Zvažte spuštění následující agregační operace, která demonstruje výše uvedený koncept:

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

Pokud používáte $where , zkuste svůj dotaz bez uzavřených závorek:

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

Lepší dotaz by byl zkontrolovat existenci pole a poté zkontrolovat délku:

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

nebo:

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

MongoDB vyhodnocuje non-$where operace dotazu před $where výrazy a jiné než $where dotazovací příkazy mohou používat index. Mnohem lepší výkon je uložit délku řetězce jako další pole a pak v něm můžete indexovat nebo vyhledávat; použití $where bude ve srovnání s tím mnohem pomalejší. Doporučuje se používat JavaScriptové výrazy a $where operátora jako poslední možnost, když nemůžete data strukturovat jiným způsobem, nebo když pracujete s malou podmnožinou dat.

Odlišný a rychlejší přístup, který se vyhýbá použití $where operátor je $regex operátor. Zvažte následující vzor, ​​který hledá

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

Poznámka – Z dokumentů :

Pokud pro pole existuje index, MongoDB porovná regulární výraz s hodnotami v indexu, což může být rychlejší než skenování kolekce. Další optimalizace může nastat, pokud je regulární výraz „výraz předpony“, což znamená, že všechny potenciální shody začínají stejným řetězcem. To umožňuje MongoDB vytvořit „rozsah“ z této předpony a porovnávat pouze s těmi hodnotami z indexu, které spadají do tohoto rozsahu.

Regulární výraz je „výraz předpony“, pokud začíná znakem acaret (^) nebo levou kotvu (\A) , následovaný řadou jednoduchých symbolů. Například regulární výraz /^abc.*/ bude optimalizováno porovnáním pouze s hodnotami z indexu, které začínají abc .

Navíc, zatímco /^a/, /^a.*/, a /^a.*$/ odpovídají ekvivalentním řetězcům, mají různé výkonnostní charakteristiky. Všechny tyto výrazy používají index, pokud existuje vhodný index; nicméně /^a.*/ a /^a.*$/ jsou pomalejší. /^a/ může zastavit skenování po spárování předpony.



  1. Relace NodeJS + ExpressJS + RedisStore není definována

  2. Seskupit podle stavu v MongoDB

  3. Použití Cloudera Data Engineering k analýze dat programu ochrany výplaty

  4. Jak vypsat všechny databáze MongoDB v Node.js?