2012-02-04 79 views
1

我一直在阅读mongodocs和阅读教程。MongoDB链接/嵌入/引用

出于测试目的,我用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 2012-02-06 14:46:07

回答

2

我从谷歌组答复,所以原谅我,如果答案似乎从上面张贴的答案。 “

”2-“嵌入”订单是否反映物品价格的变化,反映变化。“

永远不要想象用户下了订单,然后在发货之前突然意识到价格已经改变,没有明显的原因。您应该在订购时复制价格并将其放置在嵌入式产品列表中。这是大多数(如果不是全部的话)电子商务网站所做的。

“在产品集合中插入相同的产品,并且在每个订单集合中放置一个订单,差异是 产品与订单”相关“的方式,在一个链接中,最后被引用。“

这三者中的任何一个都是有效的,这取决于当然如何完成植入。如果您在订单中嵌入订购的产品,那么很好,在产品中嵌入订单并不是一个合理的解决方案。由于我怀疑任何人都会订购足够的产品来超过16Mb的限制,因此您应该是安全的。

希望这有助于

+0

确实有帮助!,因此,文献时是指嵌入式关系,更像是一种“概念”关系,除非你明确地做到了,否则数据库不会改变任何价值,不是吗?真的很感谢答案,非常丰富,事实上,我想,在更像“FOO/BAR”的例子中,良好的实践反应非常受欢迎! – slothy 2012-02-06 17:17:01

+0

我想这是“概念性”,因为嵌入式关系不影响另一个表中的数据(假设它是嵌入式关系而不是嵌入式表,两者不同),并且您必须手动建立它们之间的链接在您的客户端代码中,请记住Mongo没有连接。如果您想要更深入的解释,我可以编辑我的答案。 – Sammaye 2012-02-06 17:31:00

+0

不,确实没关系,文档中的关系/非关系比较太多了,让我感到困惑。 – slothy 2012-02-06 17:42:58