MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Listy MongoDB - zdobądź każdy N-ty element

Wygląda na to, że twoje pytanie wyraźnie dotyczyło „zdobądź co n-ty przypadek”, co wydaje się być całkiem jasnym pytaniem.

Operacje zapytań, takie jak .find() może naprawdę zwrócić dokument "tak jak jest" z wyjątkiem ogólnego pola "wybór" w projekcji i operatorów, takich jak pozycyjny $ operator dopasowania lub $elemMatch które pozwalają na pojedynczy dopasowany element tablicy.

Oczywiście istnieje $slice , ale to tylko pozwala na "wybór zakresu" w tablicy, więc znowu nie ma zastosowania.

"Jedyne" rzeczy, które mogą modyfikować wynik na serwerze to .aggregate() i .mapReduce() . Ten pierwszy w żaden sposób nie „gra bardzo dobrze” z „cięciem” tablic, przynajmniej nie przez „n” elementów. Jednak ponieważ argumenty "function()" mapReduce są oparte na logice JavaScript, masz trochę więcej miejsca do zabawy.

W procesach analitycznych i do celów analitycznych „tylko” wystarczy filtrować zawartość tablicy za pomocą mapReduce przy użyciu .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
)

W tym momencie jest to tak naprawdę tylko „biegacz JavaScript”, ale jeśli jest to tylko do analizy/testowania, to ogólnie nie ma nic złego w tej koncepcji. Oczywiście dane wyjściowe nie są „dokładnie” zbudowane tak, jak twój dokument, ale są one tak bliskie, jak tylko mapReduce.

Inna sugestia, którą tu widzę, wymaga utworzenia nowej kolekcji ze wszystkimi elementami „zdenormalizowanymi” i wstawienia „indeksu” z tablicy jako części unikalnego _id klucz. Może to dać coś, co można bezpośrednio zapytać, ale dla „każdego n-tego elementu” nadal musiałbyś zrobić:

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

Więc wypracuj i podaj wartość indeksu „co n-tego elementu”, aby uzyskać „co n-ty element”. Więc to naprawdę nie rozwiązuje problemu, o który pytano.

Jeśli formularz wyjściowy wydawałby się bardziej pożądany do celów „testowych”, lepszym kolejnym zapytaniem dotyczącym tych wyników byłoby użycie potoku agregacji z $redact

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

To przynajmniej używa "warunku logicznego" podobnego do tego, który został zastosowany w .filter() wcześniej, aby po prostu wybrać pozycje "n-tego indeksu" bez wymieniania wszystkich możliwych wartości indeksu jako argumentu zapytania.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Czy istnieje opcja upsert w poleceniu wstawiania mongodb?

  2. Jak zainicjować zestaw replikacji mongodb bez wywoływania rs.initiate()?

  3. Jak scalić pole tablicy w dokumencie w agregacji Mongo

  4. Policz komentarze w poście w Meteor

  5. Jaki jest najlepszy graficzny interfejs użytkownika MongoDB? — Aktualizacja 2019