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

Seznamy MongoDB – získejte každou N-tou položku

Zdá se, že vaše otázka byla jasně položena „získej každou n-tou instanci“, což se zdá jako docela jasná otázka.

Dotazovací operace jako .find() může skutečně vrátit dokument pouze „tak, jak je“, s výjimkou obecného pole „výběr“ v projekci a operátorů, jako je poziční $ operátor shody nebo $elemMatch které umožňují singulární párovaný prvek pole.

Samozřejmostí je $slice , ale to pouze umožňuje "výběr rozsahu" na poli, takže opět neplatí.

„Jediné“ věci, které mohou změnit výsledek na serveru, jsou .aggregate() a .mapReduce() . První jmenovaný si v žádném případě „nehraje moc dobře“ s „řezáním“ polí, alespoň ne podle „n“ prvků. Protože však argumenty "function()" mapReduce jsou logiky založené na JavaScriptu, máte o něco více prostoru na hraní.

Pro analytické procesy a „pouze“ pro analytické účely pak stačí filtrovat obsah pole přes mapReduce pomocí .filter() :

db.collection.mapReduce(
    function() {
        var id = this._id;
        delete this._id;

        // filter the content of "instances" to every 3rd item only
        this.instances = this.instances.filter(function(el,idx) {
            return ((idx+1) % 3) == 0;
        });
        emit(id,this);
    },
    function() {},
    { "out": { "inline": 1 } } // or output to collection as required
)

V tomto bodě je to opravdu jen "běžec JavaScriptu", ale pokud je to jen pro analýzu/testování, pak na tomto konceptu není obecně nic špatného. Výstup samozřejmě není "přesně" tak, jak je strukturován váš dokument, ale je tak blízký faksimile, jak se mapReduce může dostat.

Další návrh, který zde vidím, vyžaduje vytvoření nové kolekce se všemi „denormalizovanými“ položkami a vložení „indexu“ z pole jako součást jedinečného _id klíč. To může vytvořit něco, na co se můžete přímo dotazovat, ale pro „každou n-tou položku“ byste stále museli udělat:

db.resultCollection.find({
     "_id.index": { "$in": [2,5,8,11,14] } // and so on ....
})

Takže pracujte a zadejte hodnotu indexu „každá n-tá položka“, abyste získali „každou n-tou položku“. Nezdá se tedy, že by to skutečně vyřešilo problém, na který byl položen.

Pokud by se výstupní formulář zdál pro vaše „testovací“ účely vhodnější, pak by bylo lepší následné dotazování na tyto výsledky pomocí agregačního kanálu s $redact

db.newCollection([
    { "$redact": {
        "$cond": {
            "if": {
                "$eq": [ 
                    { "$mod": [ { "$add": [ "$_id.index", 1] }, 3 ] },
                0 ]
            },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }
    }}
])

To přinejmenším používá "logickou podmínku" podobnou té, která byla použita s .filter() dříve, abyste vybrali pouze položky "n-tého indexu" bez uvedení všech možných hodnot indexu jako argumentu dotazu.



  1. Sharding s jarním mongo

  2. jak nastavit mongod --dbpath

  3. Jak číst konkrétní pár klíč-hodnota z kolekce mongodb

  4. Maximální počet databází podporovaných MongoDB