我的目标是创建一个电子商务网站,客户可以在任何产品页面上看到相关产品(类似于amazon.com)。
我不知道如何开始这么艰巨的任务。根据我的研究,我的猜测是做以下事情:
创建Category
种类:
class Category(ndb.Model):
name = ndb.StringProperty()
每当创建产品时,通过祖先关系将其与类别相关联:
parent_category = ndb.Key("Category", "Books")
new_product = Product(
title="Coding Horrors Book",
parent=parent_category).put()
现在,在每个产品页面上,我都可以创建一个查询,将图书清单作为相关产品返回。
我对这种方法有些担忧:
首先,这不是一种坚实的方法。
如何指定产品类别之间的层次关系?例如,如果我们有两个产品类别,“AngularJS”,“VueJS”,我们如何指定这两个类别以某种方式相关?
答案 0 :(得分:2)
首先,澄清一下,实体血统不是强制建立关系的(并且它有一些缺点),请参阅Can you help me understand the nbd Key Class Documentation or rather ancestor relationship?。和相关的Ancestor relation in datastore
您需要考虑Balancing Strong and Eventual Consistency with Google Cloud Datastore。
答案的其余部分假设没有使用实体祖先。
要将产品与某个类别(或多个产品,如果您需要,使用repeated properties)相关联,您可以:
class Product(ndb.Model):
name = ndb.StringProperty()
category = ndb.KeyProperty(kind='Category', repeated=True)
category = ndb.Key("Category", "Books")
new_product = Product(title="Coding Horrors Book",
category=[category]).put()
这种方法存在可扩展性问题:如果产品属于多个类别,更新类别列表会变得越来越慢(整个实体,逐渐增长,每次都需要重写),如果属性被编入索引,它对exploding indexes problem很敏感。
将产品类别关系存储为单独的实体可以避免这种情况:
class ProductCategory(ndb.Model):
product = ndb.KeyProperty(kind='Product')
category = ndb.KeyProperty(kind='Category')
更好地扩展,但在这种情况下,您需要ProductCategory
查询来确定产品的相关类别实体的键,然后进行键查找以获取这些类别的详细信息,行:
category_keys = ProductCategory.query(ProductCategory.product == product_key) \
.fetch(keys_only=True, limit=500)
if category_keys:
categories = ndb.get_multi(category_keys)
logging.info('product %s categories: %s' \
% (product.title, ','.join([c.name for c in categories])))