摘要:因為他們可能會有許多顧客對相同的商品目錄進行多次請求。然而,對于我們的參考架構,我們想完全在中實現一個多方面搜索。
本文源地址:http://www.mongoing.com/blog/retail-reference-architecture-part-1
如今,產品目錄數據管理對零售商而言是一個非常復雜的問題。經過多年對多個龐大、由供應商提供的系統的依賴之后,零售商目前正在重新考慮他們的選擇,并且開始展望未來。
在如今供應商提供的系統中,產品數據必須得頻繁地使用 ETL 工具來回遷移,以保證所有的系統均在相同數據集上進行操作。這個方法就開發和管理而言是非常緩慢、容易出錯,并且非常昂貴的。因此,零售商目前正在努力將數據服務多帶帶作為一個集中的、面向服務架構(SOA)的一部分。
這是我們在MongoDB中通常看到的一個模式,因此我們開始定義一些最佳實踐以及專門面向于電商空間的參考架構。作為該成果的一部分,今天我們將開始介紹如何使用MongoDB實現一項目錄服務,并將其作為在零售商架構系列(共三部分)的第一部分。
為什么選擇MongoDB?許多不同的數據庫類型都可以實現我們的產品目錄用戶案例,那么為什么要選擇MongoDB呢?
文檔靈活性:每個MongoDB文檔都可以將數據存儲為豐富的JSON結構。這就使得MongoDB對于存儲任何對象都非常理想,包括擁有每個商品都有成千上萬系列的龐大目錄。
動態的模式:每個文檔中的JSON結構可以隨時進行調整,保證了需要修改時數據的靈活性以及易重構性。在MongoDB中,這些多重模式可以存儲于一個單一的集合中,也可以使用共享索引,保證了新、舊格式的同步高效搜索。
有表現力的查詢語言:能夠在多個文檔屬性之間進行查詢的能力簡化了許多任務。這也可以通過減少數據庫必要請求次數來提高應用的性能。
索引:MongoDB從一開始就提供了強大的二級、復合及地理索引選項,保證了像排序以及基于位置的查詢之類的特色。
數據一致性:默認地,所有的讀寫操作都會被送到一個MongoDB復制集的主節點上。這樣就保證了強一致性——一個對零售商而言非常重要的特性。因為他們可能會有許多顧客對相同的商品目錄進行多次請求。
地理分布的復制集:由數據源與用戶之間的地理距離帶來的網絡延遲是一個難題,尤其對于一個期望維持大量低延遲讀取的目錄服務而言。MongoDB的復制集可以是地理上分離的,因此它們距離用戶非常近,在很多情況下可以保證快速存取、減輕內容分發網絡的需求。
這些只是MongoDB成為對電商而言很好的選擇的一些特性。接下來,我們將介紹一下如何將其中的一部分特性運用于我們的零售商參考架構,來支持許多特色,包括:
對商品及商品系列的搜索
對商品在每個店鋪價格的檢索
允許目錄的多方面搜索和瀏覽
商品數據模型
我們需要考慮的第一件事就是商品的數據模型。在下面的例子中,我們只展示了對每件商品而言最重要的信息,例如類別、品牌以及描述:
{ “_id”: “30671”, //main item ID “department”: “Shoes”, “category”: “Shoes/Women/Pumps”, “brand”: “Calvin Klein”, “thumbnail”: “http://cdn.../pump.jpg”, “title”: “Evening Platform Pumps”, “description”: “Perfect for a casual night out or a formal event.”, “style”: “Designer”, … }
這種簡單的數據模型允許我們非常容易基于最重要原則對商品進行查詢。例如,使用db.collection.findOne,將會返回一個滿足一個查詢的單一文檔:
通過ID得到商品:db.definition.findOne({_id:”301671”})
通過一系列產品ID得到商品:db.definition.findOne({_id:{$in:[”301671”,”452318”]}})
通過類別前綴得到商品:db.definition.findOne({category:/^Shoes/Women/})
注意第二個和第三個查詢分別是如何使用$in操作符以及一個正則表達式的。當在正確索引的文檔中執行這些類型的查詢時,MongoDB可以為這些類型的查詢提供高吞吐量以及低延遲的能力。
系列數據模型對產品目錄而言另一個重要的考量是商品系列,例如現有尺寸、顏色以及風格。上述的數據模型只能獲取到關于每個目錄商品一小部分的數據。因此,對于所有現有的、我們也許需要檢索的商品系列(例如大小和顏色)而言又該怎么處理呢?
一個選擇是在一個單一文檔中存儲一個商品以及它所有的系列。這種方法擁有能夠在一個單一查詢中檢索一個商品以及其所有系列的優點。然而,它并不是在所有情況下都是最好的方法。避免無限制的文檔增長是一個非常重要的最佳實踐。如果產品系列的數據以及它們相關數據非常小,在商品文檔中存儲這些數據也許會有意義。
另一個選擇是創建一個能夠關聯到主商品的、多帶帶的系列數據模型:
{ “_id”: ”93284847362823”, //variant sku “itemId”: “30671”, //references the main item “size”: 6.0, “color”: “red” … }
這個數據模型允許我們通過它們的商品編號來快速檢索到特定的商品系列:
db.variation.find({_id:”93284847362823”})
也可以通過對itemId 屬性的查詢獲得某個特定商品的所有系列:
db.variation.find({itemId:”30671”}).sort({_id:1})
通過這個方法,我們同時維護了在目錄中展示主商品以及當用戶請求一個更詳細的產品視圖時對每個系列的快速查詢。我們也可以保證商品以及系列文檔的一個可預測大小。
不同店鋪不同價格在定義產品目錄的參考架構時另一個考慮是價格。我們已經看到了一些方法,能夠結構化我們的商品,以直接或基于特定屬性快速檢索商品。價格有可能受很多因素影響,例如店鋪的位置。我們需要一個方法快速檢索出任何一個給定商品或者商品系列的特定價格。這對于大型零售商而言是非常困難的,因為一個擁有一百萬商品以及一千個商店的商品目錄意味著我們必須在一個十億文檔集合中進行查詢以獲得任意一個給定商品的價格。
當然,我們也可以將每個系列的價格作為一個嵌套文檔在商品文檔中存儲起來,但是一個更好的解決方法是再次利用MongoDB可以對_id 進行快速查詢的優點。例如,如果產品目錄中每個商品都被一個商品ID引用,同時它的每個系列都被一個商品編號(SKU)索引,那么我們就可以將每個文檔的_id設置為商品ID或者商品編號(SKU)的一個級聯,并且將商店ID與價格變量相關聯。通過使用這個模型,上面提到的每雙單鞋的_id以及它的紅色種類應該看起來是這樣的:
商品:30671_store23
某個特定規格的商品:93284847362823_store23
這種方法也為處理價格提供很大的靈活性,因為它允許我們在商品或者系列級別對商品進行定價。我們可以查詢所有價格或者只是某個特定店鋪的價格:
所有價格:db.prices.find({_id:/^30671/})
某個特定店鋪的價格:db.prices.find({_id:/^30671_store23/})
我們甚至可以添加其他組合,例如每個店鋪群的價格,然后在單個查詢中使用$in操作符獲取對于一個商品而言所有可能的價格:
db.prices.find({_id:{$in:[ “30671_store23”, “30671_sgroup12”, “93284847362823_store23”, “93284847362823_sgroup12” ]}})瀏覽和搜索商品
對我們的產品目錄而言,最大的一個挑戰就是能夠提供多方面的搜索和瀏覽。盡管許多用戶想要使用某個特定商品或者他們正在尋找的條件來搜索我們的產品目錄,但是更多的其他用戶想要的是瀏覽,然后通過一系列屬性來限制返回結果。因此,給定創建一個像下面這個頁面一樣的需求:
我們有許多的挑戰:
響應時間:在用戶瀏覽的同時,結果的每個頁面應該在毫秒內返回。
多個屬性:伴隨著用戶選擇不同的方面(例如,品牌、大小、顏色等),新的查詢必須能夠在多個文檔屬性中運行。
系列級別屬性:一些用戶選擇的屬性將會在商品級別進行查詢,例如品牌,但是其它的查詢則有可能運行于系列級別上,例如尺寸。
多個系列:每個商品都有可能有成千上萬個系列,但是我們只希望每個商品只展示一次,因此,結果必須消除重復項。
排序:用戶需要能夠在多個屬性上進行排序,例如價格、尺寸,此外排序操作必須能夠高效運行。
分頁:每個頁面只返回少量結果,這就要求確定性排序。
許多零售商也許會想要使用一個專用的搜索引擎作為這些特色的基礎。MongoDB就提供了一個開源的連接件項目,它允許MongoDB和Apache Solr 以及Elasticsearch同時使用。然而,對于我們的參考架構,我們想完全在MongoDB中實現一個多方面搜索。
{ “_id”: “30671”, “title”: “Evening Platform Pumps”, “department”: “Shoes”, “Category”: “Women/Shoes/Pumps”, “price”: 149.95, “attrs”: [“brand”: “Calvin Klein”, …], “sattrs”: [“style”: ”Designer”, …], “vars”: [ { “sku”: “93284847362823”, “attrs”: [{“size”: 6.0}, {“color”: “red”}, …], “sattrs”: [{“width”: 8.0}, {“heelHeight”: 5.0}, …], }, … //Many more SKUs ] }
為了實現這個功能,我們創建了另一個集合,用于存儲所謂的摘要文檔。這些文檔包含了我們需要基于多個搜索方面對產品目錄中商品進行快速檢索的所有信息。
注意:在這個數據模型中,我們定義了屬性以及輔助屬性。盡管一個用戶也許會希望能夠在某個商品或者商品系列的許多不同屬性上進行搜索,但是我們只會保存一個最經常使用的核心集合。例如,給定一雙鞋,對于一個用戶而言,基于現有尺寸大小的查詢會比基于后跟高度查詢更普遍。通過在我們的數據模型中同時使用attr和sattr屬性,我們可以將所有商品屬性提供給搜索,但是也會帶來只索引最經常使用的屬性attr花費的提高。
通過使用這個數據模型,我們可以創建以下復合索引:
部門+屬性+類別+ _id
部門+變量屬性+類別+ _id
部門+類別+ _id
部門+價格+ _id
部門+評分+ _id
在這些目錄中,我們經常從部門開始,然后我們假設用戶將會選擇部門來重新定義他們的搜索結果。對于沒有部門的一個產品目錄,我們可以非常輕易地從另一個像類別或者類型等比較普遍的方面開始。然后,我們可以執行需要進行多方面搜索的查詢,并且快速將結果返回到頁面:
從商品ID獲取摘要 db.variation.find({_id:”30671”})
獲取特定商品系列的摘要 db.variation.find({vars.sku:”93284847362823”},{“vars.$”:1})
通過部門獲取所有商品的摘要 db.variation.find({department:”Shoes”})
使用一系列混合的參數獲取摘要
db.variation.find({ “department”:”Shoes”,
“vars.attr”: {“color”:”red”},
“category”: “^/Shoes/Women”})
今天我們了解了一些多功能商品目錄系統的建模和索引的最佳實踐,包括商品及商品系列的查詢、店鋪價格以及支持多樣化搜索的目錄瀏覽。使用這些方法作為一個起點,將會幫助你找到對于你自己的項目而言最好的設計。
了解更多為了進一步了解如何使用MongoDB重新開啟你的零售商之旅,請閱讀我們的白皮書。在這篇文章中,你將會了解新的零售挑戰以及MongoDB如何解決它們。
為了了解MongoDB的咨詢團隊如何可以幫助您的應用更快起步,探索我們的開始啟動指南。
快速啟動你的應用
本文譯自:https://www.mongodb.com/blog/post/retail-reference-architecture-part-1...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/17481.html
摘要:因為他們可能會有許多顧客對相同的商品目錄進行多次請求。然而,對于我們的參考架構,我們想完全在中實現一個多方面搜索。 本文源地址:http://www.mongoing.com/blog/retail-reference-architecture-part-1 如今,產品目錄數據管理對零售商而言是一個非常復雜的問題。經過多年對多個龐大、由供應商提供的系統的依賴之后,零售商目前正在重新考...
摘要:在這些系統中,單個店鋪維護他們各自的庫存,然后在某個特定的時間間隔之后通常是晚上將數據返回關系型數據庫管理系統中心。接著,關系型數據庫管理系統將當天接收到的所有數據整合和分類之后,用于分析報表等操作,并且將其提供給外部及內部應用。 本文源地址:http://www.mongoing.com/blog/retail-reference-architecture-part-2-appr.....
摘要:在這些系統中,單個店鋪維護他們各自的庫存,然后在某個特定的時間間隔之后通常是晚上將數據返回關系型數據庫管理系統中心。接著,關系型數據庫管理系統將當天接收到的所有數據整合和分類之后,用于分析報表等操作,并且將其提供給外部及內部應用。 本文源地址:http://www.mongoing.com/blog/retail-reference-architecture-part-2-appr.....
閱讀 767·2023-04-25 15:13
閱讀 1388·2021-11-22 12:03
閱讀 816·2021-11-19 09:40
閱讀 1897·2021-11-17 09:38
閱讀 1702·2021-11-08 13:18
閱讀 649·2021-09-02 15:15
閱讀 1760·2019-08-30 15:54
閱讀 2623·2019-08-30 11:12