sql >> Databasteknik >  >> NoSQL >> MongoDB

Hur kan jag välja ett antal poster per ett specifikt fält med mongodb?

Du kan inte göra detta med hjälp av aggregeringsramverket ännu - du kan få $max eller toppdatumvärdet för varje grupp men aggregeringsramverket har ännu inte ett sätt att samla topp N och det finns inget sätt att skjuta in hela dokumentet i resultatuppsättningen (endast enskilda fält).

Så du måste falla tillbaka på MapReduce. Här är något som skulle fungera, men jag är säker på att det finns många varianter (alla kräver på något sätt sortering av en array av objekt baserat på ett specifikt attribut, jag lånade min lösning från en av svaren i den här frågan .

Kartfunktion - matar ut gruppnamnet som en nyckel och hela resten av dokumentet som värdet - men den matar ut det som ett dokument som innehåller en array eftersom vi kommer att försöka samla en array av resultat per grupp:

map = function () { 
    emit(this.name, {a:[this]}); 
}

Reduceringsfunktionen kommer att samla alla dokument som tillhör samma grupp i en array (via concat). Observera att om du optimerar reducera för att bara behålla de fem översta matriselementen genom att kontrollera datum, behöver du inte slutföra funktionen, och du kommer att använda mindre minne när du kör mapreduce (det kommer också att gå snabbare).

reduce = function (key, values) {
    result={a:[]};
    values.forEach( function(v) {
        result.a = v.a.concat(result.a);
    } );
    return result;
}

Eftersom jag behåller alla värden för varje nyckel behöver jag en slutföringsfunktion för att bara dra ut de senaste fem elementen per nyckel.

final = function (key, value) {
      Array.prototype.sortByProp = function(p){
       return this.sort(function(a,b){
       return (a[p] < b[p]) ? 1 : (a[p] > b[p]) ? -1 : 0;
      });
    }

    value.a.sortByProp('date');
    return value.a.slice(0,5);
}

Genom att använda ett malldokument som liknar det du angav kör du detta genom att anropa kommandot mapReduce:

> db.top5.mapReduce(map, reduce, {finalize:final, out:{inline:1}})
{
    "results" : [
        {
            "_id" : "group1",
            "value" : [
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe13"),
                    "name" : "group1",
                    "date" : ISODate("2013-04-17T20:07:59.498Z"),
                    "contents" : 0.23778377776034176
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe0e"),
                    "name" : "group1",
                    "date" : ISODate("2013-04-17T20:07:59.467Z"),
                    "contents" : 0.4434165076818317
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe09"),
                    "name" : "group1",
                    "date" : ISODate("2013-04-17T20:07:59.436Z"),
                    "contents" : 0.5935856597498059
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe04"),
                    "name" : "group1",
                    "date" : ISODate("2013-04-17T20:07:59.405Z"),
                    "contents" : 0.3912118375301361
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfdff"),
                    "name" : "group1",
                    "date" : ISODate("2013-04-17T20:07:59.372Z"),
                    "contents" : 0.221651989268139
                }
            ]
        },
        {
            "_id" : "group2",
            "value" : [
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe14"),
                    "name" : "group2",
                    "date" : ISODate("2013-04-17T20:07:59.504Z"),
                    "contents" : 0.019611883210018277
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe0f"),
                    "name" : "group2",
                    "date" : ISODate("2013-04-17T20:07:59.473Z"),
                    "contents" : 0.5670706110540777
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe0a"),
                    "name" : "group2",
                    "date" : ISODate("2013-04-17T20:07:59.442Z"),
                    "contents" : 0.893193120136857
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe05"),
                    "name" : "group2",
                    "date" : ISODate("2013-04-17T20:07:59.411Z"),
                    "contents" : 0.9496864483226091
                },
                {
                    "_id" : ObjectId("516f011fbfd3e39f184cfe00"),
                    "name" : "group2",
                    "date" : ISODate("2013-04-17T20:07:59.378Z"),
                    "contents" : 0.013748752186074853
                }
            ]
        },
        {
            "_id" : "group3",
                        ...
                }
            ]
        }
    ],
    "timeMillis" : 15,
    "counts" : {
        "input" : 80,
        "emit" : 80,
        "reduce" : 5,
        "output" : 5
    },
    "ok" : 1,
}

Varje resultat har _id som gruppnamn och värden som array av de senaste fem dokumenten från samlingen för det gruppnamnet.



  1. Vad är fördelen med Redis-klustring på olika värdar?

  2. Hur man konverterar strängarray till sträng genom att behålla innehållet i array som kommaseparerade värden i MongoDB 4.0

  3. En introduktion till MongoDB Zone Basics

  4. Hierarkisk struktur Firestore och undersamlingar