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

Jak projekt DBRef na Spring MongoDB Aggregation?

1. Z MongoDB w wersji 3.4

Oto następujące kolekcje, które stworzyłem, aby odtworzyć Twój przypadek użycia:

Kolekcja alertów

{ 
    "_id" : ObjectId("59e6ff3d9ef9d46a91112890"), 
    "_class" : "es.bisite.usal.bulltect.persistence.entity.AlertEntity", 
    "level" : "INFO", 
    "title" : "Alerta de Prueba", 
    "payload" : "Alerta de Prueba", 
    "create_at" : ISODate("2017-10-18T07:13:45.091+0000"), 
    "delivery_mode" : "PUSH_NOTIFICATION", 
    "delivered" : false, 
    "parent" : DBRef("parents", ObjectId("59e6ff369ef9d46a91112878")), 
    "son" : DBRef("children", ObjectId("59e72ff0572ae72d8c063666"))
}
{ 
    "_id" : ObjectId("59e6ff6d9ef9d46a91112892"), 
    "_class" : "es.bisite.usal.bulltect.persistence.entity.AlertEntity", 
    "level" : "WARNING", 
    "title" : "Token de acceso inv�lido.", 
    "payload" : "El token de acceso YOUTUBE no es valido", 
    "create_at" : ISODate("2017-10-18T07:14:53.449+0000"), 
    "delivery_mode" : "PUSH_NOTIFICATION", 
    "delivered" : false, 
    "parent" : DBRef("parents", ObjectId("59e6ff369ef9d46a91112878")), 
    "son" : DBRef("children", ObjectId("59e72ff0572ae72d8c063666"))
}
{ 
    "_id" : ObjectId("59e6ff6d9ef9d46a91112893"), 
    "_class" : "es.bisite.usal.bulltect.persistence.entity.AlertEntity", 
    "level" : "WARNING", 
    "title" : "Token de acceso inv�lido.", 
    "payload" : "El token de acceso INSTAGRAM no es v�lido", 
    "create_at" : ISODate("2017-10-18T07:14:53.468+0000"), 
    "delivery_mode" : "PUSH_NOTIFICATION", 
    "delivered" : false, 
    "parent" : DBRef("parents", ObjectId("59e6ff369ef9d46a91112878")), 
    "son" : DBRef("children", ObjectId("59e72ffb572ae72d8c063669"))
}

Zauważ, że zmieniłem OBjectIds odniesienia sons, aby pasowały do ​​utworzonej przeze mnie kolekcji dzieci.

Kolekcja dzieci

{ 
    "_id" : ObjectId("59e72ff0572ae72d8c063666"), 
    "name" : "Bob"
}
{ 
    "_id" : ObjectId("59e72ffb572ae72d8c063669"), 
    "name" : "Tim"
}

Ponieważ używasz odwołania, nie możesz po prostu uzyskać dostępu do pola z innej kolekcji. Myślę więc, że brakuje Ci kilku kroków agregacji.

Zrobiłem co następuje:

db.getCollection('alerts').aggregate(
{
            $unwind:"$son"
        },
        {
            $group:
            {
                _id:{
                    son: "$son",
                    level: "$level"
                },
                count: { $sum: 1 }
            }
        },
        {
            $group:
                {
                    _id:{ 
                        son: "$_id.son"
                    },
                    alerts: { $addToSet: {
                        level: "$_id.level",
                        count: "$count"
                    }}

                }
         },
        { $addFields: { sonsArray: { $objectToArray: "$_id.son" } } },
        { $match: { "sonsArray.k": "$id"}  },
        { $lookup: { from: "children", localField: "sonsArray.v", foreignField: "_id", as: "name" } }
)

Otrzymałem następujące wyniki jako json:

{ 
    "_id" : {
        "son" : DBRef("children", ObjectId("59e72ffb572ae72d8c063669"))
    }, 
    "alerts" : [
        {
            "level" : "WARNING", 
            "count" : NumberInt(1)
        }
    ], 
    "sonsArray" : [
        {
            "k" : "$ref", 
            "v" : "children"
        }, 
        {
            "k" : "$id", 
            "v" : ObjectId("59e72ffb572ae72d8c063669")
        }
    ], 
    "name" : [
        {
            "_id" : ObjectId("59e72ffb572ae72d8c063669"), 
            "name" : "Tim"
        }
    ]
}
{ 
    "_id" : {
        "son" : DBRef("children", ObjectId("59e72ff0572ae72d8c063666"))
    }, 
    "alerts" : [
        {
            "level" : "INFO", 
            "count" : NumberInt(1)
        }, 
        {
            "level" : "WARNING", 
            "count" : NumberInt(1)
        }
    ], 
    "sonsArray" : [
        {
            "k" : "$ref", 
            "v" : "children"
        }, 
        {
            "k" : "$id", 
            "v" : ObjectId("59e72ff0572ae72d8c063666")
        }
    ], 
    "name" : [
        {
            "_id" : ObjectId("59e72ff0572ae72d8c063666"), 
            "name" : "Bob"
        }
    ]
}

Jeśli chcesz pozbyć się pól, które zostały dodatkowo utworzone, takich jak sonsArray itp., możesz dodać $project potok do clean Twój wynik.

2. Jeśli masz starsze wersje mongodb i możesz zmienić strukturę danych.

Jeśli zamiast używać takiego odniesienia:

"son" : DBRef("children", ObjectId("59e72ffb572ae72d8c063669"))

możesz dodać objectId syna/ów jako tablicę w następujący sposób:

"sonId" : [
        ObjectId("59e72ff0572ae72d8c063666")
    ]

następnie możesz wykonać agregację w następujący sposób:

db.getCollection('alerts').aggregate(
{
            $unwind:"$sonId"
        },
        {
            $group:
            {
                _id:{
                    sonId: "$sonId",
                    level: "$level"
                },
                count: { $sum: 1 }
            }
        },
        {
            $group:
                {
                    _id:{ 
                        sonId: "$_id.sonId"
                    },
                    alerts: { $addToSet: {
                        level: "$_id.level",
                        count: "$count"
                    }}

                }
         },
        { $lookup: { from: "children", localField: "_id.sonId", foreignField: "_id", as: "son" } }
)

Czy to jest coś, czego szukasz?




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Uzyskiwanie losowych rekordów i wyświetlanie w określonym formacie za pomocą PHP i MongoDB

  2. Zapytanie agregujące mongodb nie zwraca prawidłowej sumy przy użyciu $sum

  3. mongodb v3.2 nie działa na Macu

  4. Zarządzanie długotrwałymi operacjami w MongoDB

  5. Automatyczna sekwencja przyrostu w NestJs/Mongoose