0

我有一个产品系列。大多数产品都有一个类别、一个子类别和一个子子类别,有些只有其中的 1 或 2 个。我目前将它们存储在一个数组字段“类别”中,对于“书”类型的产品,它可能看起来像 [“german”、“literature”、“novels”](大约有 15 种类型,每种都有它们的自己的类别树)。
我想做的是进行搜索,也许有 10K 匹配,将 100 返回到浏览器,并提供一个类别列表以及查询的找到计数。我不知道类别是什么,它们也可以改变。

我正在查看的不同方式:

  • MapReduce,但我听说这“慢”并且比实时搜索更适合日常统计
  • 我得到的一个建议是 Aggregation->$group: 看了这个,但我看不出它如何计算值而不是仅仅对它们求和或求平均值。我错过了什么吗?
  • 对所有产品进行第二次搜索,只返回类别字段,这样我就可以在生产代码中进行计数
  • 对每个类别进行循环搜索,然后简单地返回光标的 count()。为此,我显然需要知道这些类别,这似乎是最后的手段..

基本上我的问题是“什么是最好的方法?”,它应该相当快,并且可以扩展。

当它起作用时,在用户单击一个类别后它是相同的 - 然后应该为该类别的子类别计算结果,如果有的话,对于子子类别以此类推。

附加信息:该集合可能会有几百万种产品,因为我们没有数据但很难对此进行测试,目前只有大约 50K 产品.. 未来的计划包括分片设置(除此之外还有很多其他数据“产品”)。
我是以正确的方式存储类别还是应该是单独的字段,这有帮助吗?现在数组中有 3 个项目,但以后可能会增加。
MongoDB的新手,到目前为止只与MySQL一起工作过很多......


明确类别;对于“书”类型的示例产品,“德语”将是主要类别,“文学”是子类别,“小说”是子类别。其他主要类别是 5-6 种其他语言(用于书籍),其他子类别例如“学术与学习”、“商业”或“旅行与语言”。然后,子子类别取决于子类别(最后,SSC 可以是“外语学习”、“社会语言学”……)。我将所有三个存储在一个字段中,作为一个数组,每个产品。
当有人在“book”类型上搜索“foo”时,它会找到 123 种英语产品、456 种德语产品、789 种法语产品。
然后当有人选择“德语”时,它会再次查询并显示找到的德语书籍的数量,按子类别(“学术和学习”中的 44,“商业”中的 57,...)。

4

1 回答 1

0

我目前将它们存储在一个数组字段“类别”中,它可能看起来像 [“german”、“literature”、“novels”]

您不应将一个数组用于三个不同的字段,即“类别”、“子类别”和“子子类别”。

另外为什么将语言存储为一个类别而不是“语言”?为数据库的“模式”添加一些逻辑,因为它会在事情变得更复杂时为您提供帮助。

如果这样做,使用聚合会更容易(这比 hadoop 更快,并且可以在分片集群中使用),因为您不必在数组内部进行查询,并且可以获得更准确的结果。由于它们的值非常小,因此字段的名称(“c”代表类别,“sc”代表子类别,“scc”代表子子类别)应该是这样的:

{ _id : xxxxxxxxxxxx , name : "A novel of german literature" , c : "german", sc : "literature", ssc : "novels" }

我想做的是进行搜索,也许有 10K 匹配,将 100 返回到浏览器,并提供一个类别列表以及查询的找到计数。我不知道类别是什么,它们也可以改变。

由于 mongo 是无模式的,因此您不必为每条记录设置所有这些字段。如果您计划在产品之间使用不同的架构,也许您应该为每个产品使用不同的集合,但这取决于您。

我想做的是进行搜索,也许有 10K 匹配,将 100 返回到浏览器,并提供一个类别列表以及查询的找到计数。我不知道类别是什么,它们也可以改变。

充分利用索引(索引有很多种,您可能应该使用不止一种),并使用 $group 和$limit的聚合来仅返回 100 条记录。

当它起作用时,在用户点击一个类别后它是相同的 - 然后应该为该类别的子类别计算结果,如果有的话,对于子子类别以此类推。

这是一个获取类别的所有子类别的示例查询(使用前面描述的模式):

 db.products.aggregate([{ $match : { "c" : "german"}},{ $group : { _id : {"c" : "$c"}, $addToSet :{ "subcategories" : "$sc"}}}])

此查询将返回当前类别存在的所有子类别的数组。

(如果您的类别是数组而不是单个字符串,则更新查询)

 db.products.aggregate([{ $match : { "c" : {$elemMatch : {"german" : 1, "english" : 1}}}},{ $group : { _id : {"c" : "$c"}, $addToSet :{ "subcategories" : "$sc"}}}])
于 2013-10-09T14:36:28.130 回答