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

$sum z grupy dokumentów i poddokumentów według $autora (MongoDB)

Nie od razu widoczne, ale możliwe. To, co musisz tutaj zrobić, to połączyć dokument najwyższego poziomu z tablicą komentarzy bez duplikowania go. Oto podejście polegające na połączeniu zawartości jako dwóch tablic w pojedynczą tablicę, a następnie $unwind grupowanie treści:

db.collection.aggregate([
    { "$group": {
        "_id": "$_id",
        "author": { 
            "$addToSet": {
                "id": "$_id",
                "author": "$author",
                "votes": "$votes"
            }
        },
        "comments": { "$first": "$comments" }
    }},
    { "$project": {
        "combined": { "$setUnion": [ "$author", "$comments" ] }
    }},
    { "$unwind": "$combined" },
    { "$group": {
        "_id": "$combined.author",
        "votes": { "$sum": "$combined.votes" }
    }},
    { "$sort": { "votes": -1 } }
])

Co daje wynik:

{ "_id" : "Jesse", "votes" : 148 }
{ "_id" : "Mirek", "votes" : 135 }
{ "_id" : "Leszke", "votes" : 13 }

Nawet jako pominięcie pierwszego $group etap i tworzenie połączonej tablicy w inny sposób:

db.collection.aggregate([
    { "$project": {
        "combined": { 
            "$setUnion": [
                { "$map": {
                    "input": { "$literal": ["A"] },
                    "as": "el",
                    "in": { 
                        "author": "$author",
                        "votes": "$votes"
                    }
                }},
                "$comments"
            ] 
        }
    }},
    { "$unwind": "$combined" },
    { "$group": {
        "_id": "$combined.author",
        "votes": { "$sum": "$combined.votes" }
    }},
    { "$sort": { "votes": -1 } }
])

Używają one operatorów, takich jak $setUnion a nawet $map które zostały wprowadzone w MongoDB 2.6. To sprawia, że ​​jest to prostsze, ale nadal można to zrobić we wcześniejszych wersjach, w których brak tych operatorów, zgodnie z tymi samymi zasadami:

db.collection.aggregate([
    { "$project": {
        "author": 1,
        "votes": 1,
        "comments": 1,
        "type": { "$const": ["A","B"] }
    }},
    { "$unwind": "$type" },
    { "$unwind": "$comments" },
    { "$group": { 
        "_id": {
          "$cond": [
              { "$eq": [ "$type", "A" ] },
              { 
                  "id": "$_id", 
                  "author": "$author",
                  "votes": "$votes"
              },
              "$comments"
          ]
        }
    }},
    { "$group": {
        "_id": "$_id.author",
        "votes": { "$sum": "$_id.votes" }
    }},
    { "$sort": { "votes": -1 } }
])

$const jest nieudokumentowany, ale obecny we wszystkich wersjach MongoDB, w których obecna jest struktura agregacji (od 2.2). Wprowadzono MongoDB 2.6 $literal który zasadniczo łączy się z tym samym kodem bazowym. Został użyty w dwóch przypadkach tutaj, aby zapewnić element szablonu dla tablicy lub jako wprowadzenie tablicy do odwijania w celu zapewnienia "binarnego wyboru" między dwoma akcjami.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. PostgreSQL a MongoDB

  2. EPEL MongoDB nie wystartuje na EC2 Amazon AMI

  3. Przechowywanie relacji przyjaciół w MongoDB?

  4. Spark do MongoDB przez Mesos

  5. Zamień wartości w tablicy MongoDB