Index

具有適當索引的 Mongodb Products 架構

  • August 11, 2018

我對具有 MYSQL 背景的 mongodb 完全陌生。

我正在開發一個擁有數百萬種產品的電子商務網站,所以我們決定從 MYSQL 遷移到 mongodb。

到目前為止,這是我作為最終模式提出的產品結構

{
   id: 12, // filterable + sortable 
   sku: 'some-sku', // filterable
   status: 'enabled', // filterable by default to get enabled products only 
   createdAt: {
       date: '22-11-2018',
       timestamp: 41231312
   },
   locales: {
       en: {
           title: 'Product Title', // searchable + sortable
           description: 'Some Rich description', 
           shortDescription: 'Some short description',// searchable
           category: 'Category name',
           brand: 'Brand name',
           tags: ['tag1', 'tag2', 'tag3'],// searchable
           attributes: {
               // filterable
               color: 'red', 
               size: 'XL' 
           },
           specifications: {
               // list of specifications
           }
       }
   },
   images: {
       main: {
           large: 'path-to-image',
           medium: 'path-to-image',
           small: 'path-to-image' 
       },
       all: [
           {
               large: 'path-to-image',
               medium: 'path-to-image',
               small: 'path-to-image'        
           }
       ]
   },
   categoryId: 562, // filterable
   brand: {
       id: 13, // filterable
       logo: 'path-to-log'
   },
   price: {
       original: 200,
       discount: {
           value: 40,
           percentage: 20 // filterable + sortable
       },
       salePrice: 160 // filterable with a min-max price range + sortable
   },
   rating: 4.5, // filterable + sortable
   reviews: [
       {
           customer: {
               id: 644121,
               name: 'Customer Name',
               review: 'Customer review',
               rating: 4, 
               createdAt: {
                   date: '22-11-2018'
               }
           }
       }
   ],
   children: [
       // list of children products same schema
   ],
   similarProducts: [
       // list of similar products ids
   ]
}

關於架構的快速說明:

搜尋/過濾器中將使用許多欄位,例如:

  • 預設情況下,僅顯示已啟用的產品。
  • title、shortDescription 和標籤作為全文搜尋。
  • 客戶還可以按 sku 類別 ID、品牌 ID、銷售價格、評級和屬性過濾產品。

客戶可以使用以下任何一種按升序/降序對產品顯示進行排序:

  • 最新/最舊:使用創建日期
  • 價格:從高到低或從低到高
  • 評級:從高到低或從低到高
  • 折扣百分比:從高到低或從低到高

所以這是我的問題:

1-根據之前的資訊,客戶可以根據他的選擇同時結合許多過濾器和不同的排序,所以我應該為所有案例創建索引嗎?

2-產品可以在多個類別中,並且子類別中的任何產品都將隱式地遞歸添加到其父類別中

例如,如果我們有以下類別樹:

運動>>衣服>>男士>>鞋子

如果一個產品在鞋類中,它也應該在之前的所有類別中。

在 MYSQL 中,我有一個 product_categories 表,product_id因此category_id我可以直接檢索目前類別的所有產品,而無需遍歷所有子項以獲取其 id。

現在我應該添加另一個名為的欄位categoriesList,該欄位將包含產品所在類別的所有 ID?

抱歉,長話短說,並在此先感謝。

根據您的要求,以下是解決方案:

  1. 您必須找到經常查詢的區域。在初始查找時,為每個案例添加索引似乎是個好主意。但是您可能需要在一段時間內對其進行修改並觀察索引使用率。官方文件中的以下聲明描述了關於索引成本的最重要的一點:

在建構索引之前,請規劃出您將執行的查詢類型,以便您可以建構引用這些欄位的索引。索引會帶來性能成本,但對於大型數據集的頻繁查詢來說,它的成本是值得的。考慮應用程序中每個查詢的相對頻率以及查詢是否證明索引是合理的。

您可以在此處找到更多詳細資訊。 2. 在這一點上你是對的。

基於給定產品架構的一些建議:

reviews嵌入到產品本身中,建議將評論移動到新集合中,因為您的集合中有數百萬個文件,如果使用者向產品添加評論,則會出現明顯的碎片化(他們必須四處移動,以防出現磁碟上的文件後空間不足)。

將類似產品放在產品文件中是不好的做法!如果添加了新產品怎麼辦?您是否瀏覽了所有以前的產品並添加了新產品?再次更新懲罰等著你!類似的產品需要由程式碼處理(可能有一些記憶體機制)。

將 created_at 更改為MongoDB ISO date。您可以在現場更有效地搜尋並進行聚合。

索引

檢查status欄位基數。如果具有enabled值的欄位遠低於所有產品的計數,則最好根據status欄位進行過濾,否則不推薦。

索引方向對於MongoDB. 並且有很多規則。例如,您有一個複合索引enabled:1, price:1, rating:1

如果您的查詢如下所示,則不能使用此索引:

db.products.find({enabled:true, rating: 4.0}).sort({price:-1})

在這裡閱讀更多:

您不需要為您使用的每個查詢創建索引。集合上的許多索引都有其自身的缺點。如果集合是寫密集型的,那麼所有索引都需要更新,這會使插入速度變慢。如果它被積極使用,它需要更多的記憶體。所以要明智地創建索引。

引用自:https://dba.stackexchange.com/questions/214568