MongoDB类别找到的集合

时间:2013-10-09 12:36:28

标签: php mongodb aggregation-framework

我有一个产品系列。大多数产品都有一个类别,一个子类别和一个子类别,有些只有1或2个。我现在将它们存储在数组字段“类别”中,它可能看起来像[“德语”,“文学”,“小说”],对于“book”类型的产品(大约有15种类型,每种类型都带有它们自己的类别树) 我想做的是搜索,可能有10K匹配,返回100到浏览器,还提供查询的已发现计数的类别列表。我不知道这些类别是什么,它们也可以改变。

我正在看的不同方式:

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

基本上我的问题是“什么是最好的方式?”,它应该相当快,并且规模。

如果这样做,在用户点击某个类别后也是如此 - 那么应该为该类别的子类别计算结果,对子子类别(如果有的话)也是如此。

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


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

1 个答案:

答案 0 :(得分:0)

  

我目前将它们存储在数组字段“类别”中,它可能看起来像[“德语”,“文学”,“小说”]

您不应将一个数组用于三个不同的字段,即“category”,“subcategory”和“sub-subcategory”。

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

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

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

我想做的是搜索,也许有10K匹配,向浏览器返回100,还会显示查询的已查找计数类别列表。我不知道这些类别是什么,它们也可以改变。

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

  

我想做的是搜索,也许有10K匹配,向浏览器返回100,还会显示查询的已查找计数类别列表。我不知道这些类别是什么,它们也可以改变。

充分利用indexes(有多种索引,您应该使用多个索引)并使用$ 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"}}}])