migrating one of the most popular ecommerce platforms to mongodb

30
Migrating One of the Most Popular eCommerce Platforms to MongoDB MongoDB Munich 2013, October 14th Aron Spohr, fashion4home GmbH, Berlin [email protected]

Upload: mongodb

Post on 07-Dec-2014

2.005 views

Category:

Technology


0 download

DESCRIPTION

Is it worthwhile to migrate a heavy SQL application to MongoDB? In this talk we show our insights and positive outcomes on the migration of a popular open source eCommerce platform (Magento) to MongoDB. The talk covers interesting migration challenges and techniques both from a data and software point of view.

TRANSCRIPT

Page 1: Migrating One of the Most Popular eCommerce Platforms to MongoDB

Migrating One of the Most Popular eCommerce Platforms to MongoDBMongoDB Munich 2013, October 14th

Aron Spohr, fashion4home GmbH, Berlin

[email protected]

Page 2: Migrating One of the Most Popular eCommerce Platforms to MongoDB

Will it blend?

Page 3: Migrating One of the Most Popular eCommerce Platforms to MongoDB

What is Magento?

● Open eCommerce platform● Serves all primary features of a Webshop● Written in PHP● Works on top of MySQL out of the box● Extensible architecture● Runs on over 180,000 sites● eBay owned since 2011

Page 4: Migrating One of the Most Popular eCommerce Platforms to MongoDB

The Shopping Cart

● Quote● Items● Addresses

● one Model for each● one MySQL-Table for each

Page 5: Migrating One of the Most Popular eCommerce Platforms to MongoDB

Data Structure

quote_id discount_amount grand_total

560 100.00 299.00

561 0.00 1028.40

item_id quote_id product_id qty price

100 560 1257 1 39.90

101 560 1349 2 140.10

address_id quote_id city street type

388 560 Munich Hauptstr. 33a shipping

389 560 Berlin Zahlstrasse 12 billing

390 561 Hamburg Geheimweg 3 shipping, billing

quote

quote_item

quote_address

Page 6: Migrating One of the Most Popular eCommerce Platforms to MongoDB

as a developer in// Loading a quote from database$quote = Mage::getModel(‘sales/quote’)->load(560);

// Loading a filtered collection of quote items from database$items = $quote->getItemCollection();$items->addFieldToFilter(‘product_id’, 1257);$items->load();

SELECT * FROM sales_quote WHERE quote_id=560;

SELECT * FROM sales_quote_item WHERE quote_id=560 AND product_id=1257;

Page 7: Migrating One of the Most Popular eCommerce Platforms to MongoDB

every Model has ● a Resource Model to load/save one record from/to DB● a Collection Model to load multiple records from DB

Persistence in

Model Resource Model

DBCollection Model

Model Model Model

App

licat

ion

Page 8: Migrating One of the Most Popular eCommerce Platforms to MongoDB

function load($object, $id) {

$stmt = “SELECT * FROM “ . $this->getTableName() . ” WHERE “ . $this->getIdFieldname() . ”=$id”;

$data = $sqlAdapter->fetchRow( $stmt );

$object->setData( $data );

}

Resource Model basics of

Page 9: Migrating One of the Most Popular eCommerce Platforms to MongoDB

function load() {

$stmt = “SELECT * FROM “ . $this->getTableName() . ” WHERE “ . $this->renderFilters();

foreach($sqlAdapter->fetchRows( $stmt ) as $row) {$object = new Object();$object->setData($data);$this->addItem($object);

}}

Collection Model basics of

Page 10: Migrating One of the Most Popular eCommerce Platforms to MongoDB

Why should we change that?

● You don’t have to● It always depends on your application

Reasons we had:● Have more/other scalability options● Make it easier to work with raw data● Be more flexible with your data schema● Learn more about the software you are using

Page 11: Migrating One of the Most Popular eCommerce Platforms to MongoDB

Let’s get started

● not change the way Magento works● a very simple, self-explainable data schema● make it easy to migrate old data● not lose any existing features

Page 12: Migrating One of the Most Popular eCommerce Platforms to MongoDB

Data Structure - mongoDB{

quote_id: 560, discount_amount: 100.00, grand_total: 299,

item: [{item_id: 100, product_id: 1257, qty: 1, price: 39.9},{item_id: 101, product_id: 1349, qty: 2, price: 140.10}

],address: [

{address_id: 388, city: ‘Munich’, street: ‘Hauptstr. 33a’, ...},{address_id: 389, city: ‘Berlin’, street: ‘Zahlstrasse 12’, ...}

]

}

Page 13: Migrating One of the Most Popular eCommerce Platforms to MongoDB

SELECT * FROM quote_item;

db.quote.find( {}, { ‘item’: 1 } );

● { ‘item’:[ {item_id: 100, product_id: 1257, qty: 1 },{item_id: 101, product_id: 1349, qty: 2 } ] }

● { ‘item’:[ {item_id: 102, product_id: 4421, qty: 1 } ] }● { ‘item’:[ {item_id: 103, product_id: 2301, qty: 1 },

{item_id: 104, product_id: 5511, qty: 1 } ] } ● ...

Do we still have a table?

Page 14: Migrating One of the Most Popular eCommerce Platforms to MongoDB

a Tool to simplify our work with mongoDB...

Page 15: Migrating One of the Most Popular eCommerce Platforms to MongoDB

Loading a collection of thingsloadDataCollection(‘/quote/item’, array());

● { item_id: 100, product_id: 1257, qty: 1 }● { item_id: 101, product_id: 1349, qty: 2 }● { item_id: 102, product_id: 4421, qty: 1 }● ...

db.quote.find( {}, { ‘item’: 1 } );

● { ‘item’:[ {item_id: 100, product_id: 1257, qty: 1},{item_id: 101, product_id: 1349, qty: 2} ] }

● { ‘item’:[ {item_id: 102, product_id: 4421, qty: 1} ] }● ...

Page 16: Migrating One of the Most Popular eCommerce Platforms to MongoDB

The path to our data

● Tells us where to find the data● Is very similar to a table name

/item/quoteName of Collection

Name of Array in document

Page 17: Migrating One of the Most Popular eCommerce Platforms to MongoDB

We rewire all Table names in

quote

quote_item

quote_address

/quote

/quote/item

/quote/address

Page 18: Migrating One of the Most Popular eCommerce Platforms to MongoDB

$rows = $newAdapter->loadDataCollection($this->getTableName(),$this->renderFilters() );

foreach($rows as $row) {$object = new Object();$object->setData($data);$this->addItem($object);

}

The new Collection Model

Page 19: Migrating One of the Most Popular eCommerce Platforms to MongoDB

loadDataCollection(‘/quote/item’, array(product_id => 1257));

● { item_id: 100, product_id: 1257, qty: 1 }● { item_id: 342, product_id: 1257, qty: 2 }● ...

db.quote.find( { ‘item.product_id’: 1257 }, { ‘item’: 1 } );

● { ‘item’:[ {item_id: 100, product_id: 1257, qty: 1} ] }● { ‘item’:[ {item_id: 342, product_id: 1257, qty: 2} ] }● ...

Loading a collection of things (filtered)

Page 20: Migrating One of the Most Popular eCommerce Platforms to MongoDB

as a developer in

// loading a filtered collection of quote items from database$items = Mage::getModel(‘sales/quote_item’)->getCollection();

$items->addFieldToFilter(‘quote_id’, 560); $items->addFieldToFilter(‘product_id’, 1257);

$items->load();

Page 21: Migrating One of the Most Popular eCommerce Platforms to MongoDB

Loading a collection of things (filtered)

loadDataCollection( ‘/quote/item’, array( ‘quote_id’ => 560, ‘product_id’ => 1257) );

db.quote.find( { ‘item.quote_id’: 560, ‘item.product_id’: 1257 }, { ‘item’: 1 } );

- no result

- no result

● This is not a relational database anymore● Quote Items may not have a quote_id in our schema

Page 22: Migrating One of the Most Popular eCommerce Platforms to MongoDB

Loading a collection of things (filtered)

loadDataCollection( ‘/quote{quote_id:560}/item’, array(product_id=> 1257));

● { item_id: 100, product_id: 1257, qty: 1 }

db.quote.find( {‘quote_id’: 560, ‘item.product_id’: 1257}, { ‘item’: 1 } );

● { ‘item’:[ {item_id: 100, product_id: 1257, qty: 1} ] }

Page 23: Migrating One of the Most Popular eCommerce Platforms to MongoDB

On-the-fly Tablename completion

/quote{quote_id:$quote_id}/item

getTablename()

/quote{quote_id:560}/item

completePath(filters, properties)

Page 24: Migrating One of the Most Popular eCommerce Platforms to MongoDB

as a developer in

// load a single item from db, change qty, save it$item = Mage::getModel(‘sales/quote_item’)->load(101);$item->setQty(2);$item->save();

// add a product to cart$item = Mage::getModel(‘sales/quote_item’);$item->setQuoteId(560)->setProductId(1566)->setQty(1);$item->save();

Page 25: Migrating One of the Most Popular eCommerce Platforms to MongoDB

Loading a single record

loadData( ‘/quote{quote_id:560}/item’, ‘item_id’, 100);findOne({ ‘quote_id’: 560, ‘item.item_id’: 100}, {‘item.$’: 1});

loadData( ‘/quote/item’, ‘item_id’, 100);loadData( ‘/quote{quote_id:$quote_id}/item’, ‘item_id’, 100);findOne({ ‘item.item_id’: 100}, {‘item.$’: 1});

Result for all three{ item_id: 100, product_id: 1257, qty: 1 }

Page 26: Migrating One of the Most Popular eCommerce Platforms to MongoDB

Saving a single record

InsertingsaveData( ‘/quote{quote_id:560}/item’,

array(‘item_id’ => 732, ‘product_id’ => 1257, ‘qty’ => 1));db.quote.update( { quote_id: 560 }, { $push : {‘item’ =>

{ item_id: 732, product_id: 1257, qty: 1 }} });

UpdatingsaveData( ‘/quote/item’, array(‘item_id’ => 732, ‘qty’ => 2));saveData( ‘/quote{quote_id:$quote_id}/item’, ...);db.quote.update( { item.item_id: 732 },

{ $set : { item.$.qty: 2 } } );

Page 27: Migrating One of the Most Popular eCommerce Platforms to MongoDB

function load($object, $id) {

$data = $adapter->loadData($this->getTablename(),$this->getIdFieldname(),$id);

$object->setData( $data );

}

The new resource model

Page 28: Migrating One of the Most Popular eCommerce Platforms to MongoDB

function save($object) {

$id = $this->getNewId();$data = $adapter->saveData(

$this->getTablename(),$this->getIdFieldname(),$id,$object->getData());

$object->setId($id);}

The new resource model

Page 29: Migrating One of the Most Popular eCommerce Platforms to MongoDB

create a simple application to● load using the old resource model● save using the new resource model

Migration of old data in

Model

Old Resource Model DB

App

licat

ion

New Resource Model

Page 30: Migrating One of the Most Popular eCommerce Platforms to MongoDB

Thanks a lot

Firefly Glow Cube

Dining Table Campagna