用于监控应用程序的Mongo数据建模

时间:2018-09-24 20:30:52

标签: mongodb

我正在尝试了解监视应用程序的最佳模型。

我有一个监视应用程序,它将每30分钟运行一次,以从目标系统获取统计信息并将详细信息存储在MongoDB中。

用例:

产品,公司

大约有2000种产品。将添加/删除产品,但每个月的增长率不会超过10%。因此,我预计未来1年不会超过3000。

公司是每种产品的消费者。每个使用该产品的公司将有1到10家公司。消费者人数也将上升或下降。

因此,在每次运行中,我们将获得产品列表以及相应的公司。产品详细信息如下:

产品:

  1. 产品名称
  2. 总数(这将提供当前可用的数字,并且每次轮询都会更改)
  3. 产品重量
  4. 使用寿命(可能会不时更改)
  5. 公司列表-谁在使用此产品

产品的样品数据:

{
            "productName" : "Small Box",
            "total" : NumberLong(1000),
            "weight" : "1.5",
            "durability" : "20",
            "companies" : [
                {
                    "name" : "Nike",
                    "taken" : NumberLong(10)
                },
                {
                    "name" : "Reebok",
                    "taken" : NumberLong(20)
                }
            ]
}

在这里,每次投票的计数都会不断变化。

网络应用程序:

将有3个屏幕显示详细信息。

  1. 仪表板-它将显示高级统计信息,例如(产品数量,公司数量,总规模....)
  2. 产品-列表视图(要查看完整列表)-在选择任何产品时将显示产品的详细信息

    在这里,我将必须显示产品详细信息,并必须列出所有消费的公司。

  3. 公司-列表视图(要查看完整列表)-将显示每个选择任何公司的公司详细信息

    在这里,我将必须显示公司详细信息及其正在使用的所有产品。

我正在存储的方式。

  1. 仪表板集合-显示统计信息,例如产品总数,公司总数...

    {             “时间” :             “ totalProducts”:NumberLong(1000),             “ totalCompanies”:“ 1.5”, }

  2. 产品集合-将具有以下详细信息。

{
                "productName" : "Small Box",
                "total" : NumberLong(1000),
                "weight" : "1.5",
                "durability" : "20",
                "companies" : [
                    {
                        "name" : "Nike",
                        "taken" : NumberLong(10)
                    },
                    {
                        "name" : "Reebok",
                        "taken" : NumberLong(20)
                    }
                ]
    }
  1. 公司集合-将包含以下详细信息
{
            "companyName" : "Nike",
            "products" : [
                {
                    "name" : "Small Box",
                    "taken" : NumberLong(10)
                },
                {
                    "name" : "Medium Box",
                    "taken" : NumberLong(20)
                }
            ] 
}

因此,在每次运行中,我都会生成唯一的ID,并将此ID添加到要存储的所有数据中。我仅将这些集合中的最后两周的数据保留下来。每天都会清理2周以上的数据。

因此,当用户来到Dashboard时,请进行排序以获取最新记录并显示详细信息。 Dashboard集合中每次运行将只有一条记录,并且将有最近2周的记录。

当用户进入“产品”屏幕时,Still将不得不从仪表板获取最新记录以获取UniqueId,并转到Products集合以获取该UniqueId的所有记录,因为每次运行大约有2000条记录。公司集合也一样。

在这里,我将必须始终显示最新数据。当用户转到“产品或公司”屏幕时,我将转到2个不同的收藏集。

还有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

请检查其可帮助您准备模式 注意:Mongo版本:3.6.5

产品组合

/* 1 */
{
    "_id" : ObjectId("5bb1e270269004e06093e178"),
    "productName" : "Small Box",
    "total" : NumberLong(1000),
    "weight" : "1.5",
    "durability" : "20",
    "companies" : [ 
        ObjectId("5bb1e2d2269004e06093e17b"), 
        ObjectId("5bb1e2d8269004e06093e17c")
    ],
    "date" : ISODate("2018-10-01T09:28:40.502Z")
}

/* 2 */
{
    "_id" : ObjectId("5bb1e293269004e06093e179"),
    "productName" : "Large Box",
    "total" : 1000.0,
    "weight" : "1.2",
    "durability" : "20",
    "companies" : [ 
        ObjectId("5bb1e2d8269004e06093e17c"), 
        ObjectId("5bb1e2de269004e06093e17d")
    ],
    "date" : ISODate("2018-10-01T09:28:40.502Z")
}

/* 3 */
{
    "_id" : ObjectId("5bb1e29d269004e06093e17a"),
    "productName" : "Medium Box",
    "total" : 1000.0,
    "weight" : "1.2",
    "durability" : "20",
    "companies" : [ 
        ObjectId("5bb1e2d2269004e06093e17b"), 
        ObjectId("5bb1e2d8269004e06093e17c"), 
        ObjectId("5bb1e2de269004e06093e17d")
    ],
    "date" : ISODate("2018-07-01T09:28:40.502Z")
}

公司收藏

/* 1 */
{
    "_id" : ObjectId("5bb1e2d2269004e06093e17b"),
    "companyName" : "Nike"
}

/* 2 */
{
    "_id" : ObjectId("5bb1e2d8269004e06093e17c"),
    "companyName" : "Reebok"
}

/* 3 */
{
    "_id" : ObjectId("5bb1e2de269004e06093e17d"),
    "companyName" : "PUMA"
}

使用comapny获取单个产品

db.getCollection('products').aggregate([{
      $match :  { "_id" : ObjectId("5bb1e270269004e06093e178") } },
       { $lookup : {
           from : 'company',
           foreignField : '_id',
           localField : 'companies',
           as : 'companies'
           }
       }
      ])

所有带有公司列表的产品

db.getCollection('products').aggregate([
       { $lookup : {
           from : 'company',
           foreignField : '_id',
           localField : 'companies',
           as : 'companies'
           }
       }
      ])

公司ID和二手产品

  db.getCollection('company').aggregate([{
          $match :  { "_id" : ObjectId("5bb1e2d2269004e06093e17b") } },
           { $lookup : {
               from : 'products',
               foreignField : 'companies',
               localField : '_id',
               as : 'products'
               }
           }
          ])

还可以通过在每个产品中添加日期字段来获得上周数据

    db.getCollection('products').aggregate([{
          $match :  { 
              date: {
                $gte: new Date(new Date() - 7 * 60 * 60 * 24 * 1000)
        } } },
           { $lookup : {
               from : 'products',
               foreignField : 'companies',
               localField : '_id',
               as : 'products'
               }
           }
    ])

获取公司的最新产品

db.getCollection('products').aggregate([
       { $sort : { date : -1} },
       { $limit : 1},
       { $lookup : {
           from : 'company',
           foreignField : '_id',
           localField : 'companies',
           as : 'companies'
           }
       }
      ])

答案 1 :(得分:0)

  

因此,每次运行时,我都会生成唯一的ID,并将此ID添加到所有要存储的数据中。我仅将这些集合中的最后两周的数据保留下来。每天都会清理2周以上的数据。

我不会那样做。我会使用_id,mongodb自动给您。并制作一个runobject来收集所有这些对象id。因为每个对象拥有1个键比336个键(48(每天30分钟)x 14(2周内的天数))更好。

我将创建一个运行对象,其中包含company_id,product_id和时间戳的数组。如果30分钟内未发生任何变化,我将只使用一个运行对象_id(与第一个相同)和一个时间戳。这样就节省了很多空间。

希望我能正确理解您,因为这对我来说很难读。