mongodb模式优化

时间:2015-04-28 05:40:52

标签: json django mongodb mongodb-query

早期查询的扩展名 Mongodb find query

在一个季节,不同的供应商销售不同的水果,他们安排他们不及货架号码。以下是我在mongodb中插入的一些记录 - vendor.json

{
  "_id" : "vendor1",
  "shelf_1": ["Pear","Banana"],
  "shelf_2" : ["Grapes", "MuskMelon", "Apricot"],
  "shelf_3" : ["Pineapple, "Kiwi fruit"],
  "shelf_4" : ["Orange"],
  "shelf_5" : ["Guava","Lemon"]
}

{
  "_id" : "vendor2",
  "shelf_1": ["Mango","Banana"],
  "shelf_2" : ["Grapes", "MuskMelon", "Peach"],
  "shelf_3" : ["Pear, "Pulm"],
  "shelf_4" : ["Jackfruit"],
  "shelf_5" : ["Apple","Apricot"],
  "shelf_6": ["Avocado","Cherry"],
  "shelf_7" : ["Clementine", "Date", "Fig"],
  "shelf_8" : ["Guava, "Honeydew melon"],
  "shelf_9" : ["Lemon"],
  "shelf_10" : ["Kiwi fruit","Elderberry"],
  "shelf_11": ["Mysore Raspberry","Mountain Apple"],
  "shelf_12" : ["Starfruit", "Scrub Cherry", "Pomegranate"],
  "shelf_13" : ["Sugar Apple, "Tropical Appricot"],
  "shelf_14" : ["chinese chestnut",passion fruit],
  "shelf_15" : ["Raspberry","Wax Apple"],
  "shelf_16": ["Blueberries"],
  "shelf_17" : ["Strawberry", "Ugli fruit", "Watermelon"],
  "shelf_18" : ["Quince, "Satsuma","quince"],
  "shelf_19" : ["Pineapple"],
  "shelf_20" : ["Peanut","Orange","blackcurrant","lime","nectarine"]
}
{
  "_id" : "vendor3",
  "shelf_1": ["Mango","Banana"],
  "shelf_2" : ["Jackfruit"],
  "shelf_3" : ["Lemon, "Pulm","Pineapple"],
  "shelf_4" : ["Orange","Guava"],
  "shelf_5" : ["Apple","Apricot"],
  "shelf_6": ["Avocado","Cherry"],
  "shelf_7" : ["Pomegranate", "Date", "Fig"],
  "shelf_8" : ["Watermelon"],
  "shelf_9" : ["Kiwi fruit","Strawberry"]
}

我在架子上和每个水果上添加了索引。这里的每个架子都包含独特的水果和这些架子上的水果排列 对于不同的供应商来说是不同的。

我想使用上面的架构

  1. 当供应商知道
  2. 时,可以找到供应商提供的货架上的水果
  3. 查找特定供应商使用的货架总数。 所以关于我创建的模式的任何建议都是为了在两个查询之上运行

1 个答案:

答案 0 :(得分:1)

虽然过度规范化会带来严重问题,但您的架构已经规范化了。

  1. 它不能很好地扩展。截至撰写本文时,有一个16MB size limit on BSON documents。如果您有一个非常大的供应商,您(理论上)可能会遇到问题。想象一下WalMart在不同地点拥有数千个货架。请记住,Facebook必须支付巨额资金,因为他们大大低估了扩展的必要性。
  2. 使用当前架构时,如果要索引所有架子,则必须具有任意数量的索引。抛开其他问题:构建索引不是免费的,即使在后台完成也是如此。
  3. 每个查询只能使用一个索引。所以我们需要减少索引的数量。
  4. 您提出的问题甚至不需要此架构。两个时候,供应商都知道。因此,您可以轻松高效地使用更传统的方法进行查询。
  5. 我将如何做到这一点。我有一个供应商架构,其中包含名称和位置等内容。接下来,我有一个架子架构。每个架子都会引用供应商,就像在SQL中一样。唯一的问题是那些引用是“弱”的,所以说。但由于供应商是已知的,因此他的_id查询货架架构也是如此。

    供应商架构

    这非常简单

    {
      '_id': new ObjectId(),
      'name': 'Acme Mart',
      'location': {
        type: 'Point',
        coordinates: [ 34.180278, -118.328333 ]
      }
    }
    

    货架架构

    实际上它也很容易

    {
      _id: new ObjectId(),
      vendor: "idOfVendor",
      description: "Shelf 14"
      contents: ["Apples", "Oranges", "Kiwi" ]
    }
    

    指数

    将供应商location字段需要的地理空间索引放在一边,以下是您需要的索引

    // Only if you want to search by name
    db.vendors.ensureIndex({name:1})
    
    // we use a compound index here
    db.shelves.ensureIndex({vendor:1,contents:1})
    

    你甚至可以在contents上使用文字索引,使搜索能够通过“苹果”找到“苹果”和“苹果”,但是你可以自行决定。

    您的查询

    由于供应商是已知的,因此他的_id,我们可以很容易地找到包含Kiwi的所有货架:

    db.shelves.find({vendor:"idOfVendor", contents: "Kiwi"})
    

    计算货架数量变得更加简单:

    db.shelves.find({vendor:"idOfVendor"}).count()