2012-02-04 2 views
1

Я читаю монгодоки и читаю учебник.MongoDB link/embed/reference

Для тестирования я сделал этот маленький скрипт с python/pymongo.

В основном, 3 DBS, с 2 коллекции каждый, «заказы» и «продукты»

Те же самые продукты вставляются в коллекции продуктов, и один заказ размещен в каждой коллекции заказа, разница «связанные» с заказами, в одном связаны друг с другом, в других встроены и последние ссылаются. Наконец, обновляет одно значение в продукте и печатает его.

Мои вопросы: 1 - Являются ли «отношения» хорошо выполненными. Переформулируйте: Это так, как делается ссылка/вставка/ссылка?

2- Если «внедренный» заказ отражает изменения в ценах товара, отражают изменения в продукте или это должно быть сделано сценарием?

# -*- coding: utf-8 *-* 
from pymongo import * 
from bson import * 

import sys 


def connect(): 
    try: 
     auxcon = Connection('localhost', 27017) 
     print "Connection: %s database_names: %s" % (
      auxcon, auxcon.database_names()) 
     return auxcon 
    except error.ConnectionFailure as cf: 
     print "Conection error: %s" % cf 
     sys.exit(0) 

def newDB(db_name, conx): 
    try: 
     ldb = database.Database(conx, db_name + "_linked") 
     edb = database.Database(conx, db_name + "_embedded") 
     rdb = database.Database(conx, db_name + "_referenced") 
     return ldb, edb, rdb 
    except (error.TypeError, error.InvalidName) as err: 
     print "Error: %s" % err 
     sys.exit(0) 

def newCollections(db_name): 
    try: 
     colprod = db_name.create_collection("products") 
     colord = db_name.create_collection("orders") 
     return colprod, colord 
    except errors.CollectionInvalid as err: 
     print "Collection alrready exists %s" % err 
     return db_name["products"], db_name["orders"] 

def insertProducts(colname): 
    product = {"name": "Tablet", "price": 200, "desc": "Android tablet"} 
    product2 = {"name": "Phone", "price": 100, "desc": "Samsung Phone"} 
    try: 
     p1 = colname.insert(product, safe=True) 
     p2 = colname.insert(product2, safe=True) 
     return p1, p2 
    except errors.OperationFailure as err: 
     print "Error inserting %s" % err 
     return None, None 


def updateProducts(colname): 
    for product in colname.find({}): 
     product["price"] = product["price"] * 110/100 
     colname.save(product) 

def printProducts(colname): 
    print "DATABASE: %s COLLECTION: %s" % (
     colname.database.name, colname.name) 
    for product in colname.find({}): 
     print product 

def findOrders(colname): 
    print "DATABASE: %s COLLECTION: %s" % (
     colname.database.name, colname.name) 
    for order in colname.find({}): 
     for key, value in order.items(): 
      print "%s : %s" % (key, value) 

if __name__ == "__main__": 
    cx = connect() 
    try: 
     cx.drop_database("carritodb_linked") 
     cx.drop_database("carritodb_embedded") 
     cx.drop_database("carritodb_referenced") 
    except errors.TypeError as err: 
     print "Error %s" % err 

    dbl, dbe, dbr = newDB("carritodb", cx) 
    licoll = newCollections(dbl) 
    emcoll = newCollections(dbe) 
    recoll = newCollections(dbr) 

    lp1, lp2 = insertProducts(licoll[0]) 
    ep1, ep2 = insertProducts(emcoll[0]) 
    rp1, rp2 = insertProducts(recoll[0]) 

    linkedOrder = {"userInfo": "Alex Martinavarro", "items_chart": [lp1, lp2]} 
    linkedOrder = licoll[1].insert(linkedOrder, safe=True) 

    embeddedOrder = {"userInfo": "Alex Martinavarro", "items_chart": []} 
    embeddedOrder = emcoll[1].insert(embeddedOrder, safe=True) 
    embeddedOrder = emcoll[1].find_one(embeddedOrder) 
    for product in emcoll[0].find({}): 
     embeddedOrder["items_chart"].append(product) 
    emcoll[1].save(embeddedOrder) 

    p1ref = dbref.DBRef(recoll[0].name, rp1) 
    p2ref = dbref.DBRef(recoll[0].name, rp2) 
    referencedOrder = {"userInfo": "Alex Martinavarro", "items": [p1ref, p2ref]} 
    referencedOrder = recoll[1].insert(referencedOrder, safe=True) 

    print "INSERTED PRODUCTS" 
    printProducts(licoll[0]) 
    printProducts(emcoll[0]) 
    printProducts(recoll[0]) 

    print "ORDERS" 
    findOrders(licoll[1]) 
    findOrders(emcoll[1]) 
    findOrders(recoll[1]) 

    """UPDATING""" 
    updateProducts(licoll[0]) 
    updateProducts(emcoll[0]) 
    updateProducts(recoll[0]) 

    print "UPDATED PRODUCTS" 
    printProducts(licoll[0]) 
    printProducts(emcoll[0]) 
    printProducts(recoll[0]) 

    print "ORDERS AFTER UPDATE" 
    findOrders(licoll[1]) 
    findOrders(emcoll[1]) 
    findOrders(recoll[1]) 
+0

этот вопрос был также размещен здесь: http://groups.google.com/group/mongodb-user/browse_thread/thread/8107173684d5da7b – Barrie

ответ

2

Я отвечаю из групп google, поэтому простите меня, если ответ кажется от того, который был выше.

"2- Если" внедренный "заказ отражает изменения в ценах товара, отразите изменение."

Никогда не представьте, что пользователь разместил заказ, а затем перед его отправкой неожиданно понял, что цена изменилась без видимых причин. Вы должны дублировать цену при заказе и поместить ее в список встроенных продуктов. Это то, что делает большинство (если не все) сайтов электронной коммерции.

«Те же продукты вносятся в коллекцию изделий, и один заказ помещается в каждую коллекцию заказов, разница составляет , так как продукты« связаны »с заказами, в одном связаны друг с другом, в других встроены и последние ссылаются ».

Любое из трех действительных в зависимости от того, как, конечно, выполняется обрезка. Если вы заказываете заказываемые товары в рамках заказов, тогда это нормально, вложение заказов в продукты не будет разумным решением. Поскольку я сомневаюсь, что кто-то закажет достаточно продуктов, чтобы превысить предел в 16 Мб, вы должны быть в безопасности.

Надеется, что это помогает,

+0

действительно помогает !, так, когда литература относится к встроенным отношениям, больше похоже на «концептуальное» отношение, db не изменяет никакой ценности, если вы специально не делаете этого, нет ?. На самом деле я ценю ответ, очень информативный, на самом деле, я думал, в чем-то более похожим на пример «FOO/BAR», ответ на хорошие практики очень приветствуется! – slothy

+0

Я предполагаю, что это «концептуально» в том, что встроенная взаимосвязь не влияет на данные в другой таблице (при условии, что это встроенная взаимосвязь, а не встроенная таблица, две разные) и что вы должны вручную сделать ссылку между ними в вашем клиентском коде, помните, что у Mongo нет объединений. Если вы хотите получить более подробное объяснение, я могу отредактировать свой ответ. – Sammaye

+0

Нет, это действительно нормально, слишком много реляционных/нереляционных сравнений в документах, смутил меня. – slothy

Смежные вопросы