我一直在阅读mongodocs并阅读教程。
出于测试目的,我用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 :(得分:2)
我正在谷歌小组回答,请原谅我,如果答案似乎与上面发布的答案不同。
“2-”嵌入式“订单是否反映了商品价格的变化,反映了变化。”
从来没有想象用户下订单然后在发货之前突然意识到价格已经发生变化而没有明显的原因。您应该在订购时复制价格并将其放入嵌入式产品列表中。这就是大多数(如果不是全部)电子商务网站所做的事情。
“产品系列中插入了相同的产品,每个订单集合中都有一个订单,区别在于 产品与订单“相关”的方式,一个是链接的,另一个是嵌入的,最后一个是引用的。“
这三个中的任何一个都是有效的,这取决于当然如何完成嵌入。如果您在订单中嵌入订购的产品那么这很好,在产品中嵌入订单将不是一个合理的解决方案。因为我怀疑任何人都会订购足够的产品来超过16Mb的限制,所以你应该是安全的。
希望这有帮助,