Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 计算一组选定类别的项目计数器_Ruby On Rails_Ruby_Data Mining - Fatal编程技术网

Ruby on rails 计算一组选定类别的项目计数器

Ruby on rails 计算一组选定类别的项目计数器,ruby-on-rails,ruby,data-mining,Ruby On Rails,Ruby,Data Mining,在我们的RubyonRails项目中,我们有很多食谱的分类标准,比如烹饪方法、场合等。每个食谱都属于其中的一个或几个类别。当有人开始浏览食谱时,他/她可以缩小到一组特定的类别。然后,我们需要计算从该集合中可访问的所有类别中的食谱数量(“可访问”表示该类别中也有属于选定类别的食谱)。这与亚马逊搜索的工作原理类似:有人输入“软件”,左边有一个菜单,上面写着“图书(200)”,“电影(300)”等等,所以用户可以通过点击这些链接来进行更深入的搜索 现在我们大致上是这样实现的: 从URL构建一组选定的类

在我们的RubyonRails项目中,我们有很多食谱的分类标准,比如烹饪方法、场合等。每个食谱都属于其中的一个或几个类别。当有人开始浏览食谱时,他/她可以缩小到一组特定的类别。然后,我们需要计算从该集合中可访问的所有类别中的食谱数量(“可访问”表示该类别中也有属于选定类别的食谱)。这与亚马逊搜索的工作原理类似:有人输入“软件”,左边有一个菜单,上面写着“图书(200)”,“电影(300)”等等,所以用户可以通过点击这些链接来进行更深入的搜索

现在我们大致上是这样实现的:

  • 从URL构建一组选定的类别
  • 执行一个查询,从属于当前选定条件的所有配方中获取类别ID
  • 构建将所有类别ID映射到配方计数的索引,并仅呈现具有非零计数器的类别ID
  • 将该索引存储在memcached中24小时,因此对于特定页面,我们每天只计算一次

  • 我担心的是,如果缓存未命中,构建索引可能需要很多时间。也许你对如何解决这个问题或改进当前的解决方案有什么建议?

    每天的索引不是很干净。插入或更新数据集时,为什么不为其编制索引

    插入数据集(如配方)

    • 启动一个线程,将内容添加到索引中

    • 如果线程(高负载!)上发生超时(如1秒),请停止它

    每日:

    • 将当前索引保存到磁盘

    • 更新整个索引

    • 如果失败,请从磁盘恢复保存的索引

    • 否则将索引读取到memcache


      • 每天的索引不是很干净。插入或更新数据集时,为什么不为其编制索引

        插入数据集(如配方)

        • 启动一个线程,将内容添加到索引中

        • 如果线程(高负载!)上发生超时(如1秒),请停止它

        每日:

        • 将当前索引保存到磁盘

        • 更新整个索引

        • 如果失败,请从磁盘恢复保存的索引

        • 否则将索引读取到memcache


        您没有对类别/产品的数量进行任何估计,但我假设其中有很多:)

        如果我想要表现,以下是我的方法:(我知道,这太疯狂了:)

        • 对于每个类别,在memcache中保留一个位向量,意思是:如果id为n的产品属于该类别,则第n位为1
        让我举个例子: 如果产品1、7、9和10属于A类,1、6、9属于B类,1、9、11属于C类,则:

        • A是01000010100000
        • B是01000010 01000000
        • C是0100000001010000
        当你想计算这些集合的交集时,只要在集合之间做一个位AND,你就会得到结果

        结果是:

        • 结果=A和B,C=01000000 01000000
        如果您想计算每个类别,只需创建另一个类别和结果

        备注:

        • 别忘了重新计算这些 关于改变事物的向量 分贝
        • 如果您计划将许多类别进行交叉,这将非常快
        • 对于每个类别,必须存储一个大于 产品总数/8

        您没有对类别/产品的数量进行任何估计,但我假设其中有很多:)

        如果我想要表现,以下是我的方法:(我知道,这太疯狂了:)

        • 对于每个类别,在memcache中保留一个位向量,意思是:如果id为n的产品属于该类别,则第n位为1
        让我举个例子: 如果产品1、7、9和10属于A类,1、6、9属于B类,1、9、11属于C类,则:

        • A是01000010100000
        • B是01000010 01000000
        • C是0100000001010000
        当你想计算这些集合的交集时,只要在集合之间做一个位AND,你就会得到结果

        结果是:

        • 结果=A和B,C=01000000 01000000
        如果您想计算每个类别,只需创建另一个类别和结果

        备注:

        • 别忘了重新计算这些 关于改变事物的向量 分贝
        • 如果您计划将许多类别进行交叉,这将非常快
        • 对于每个类别,必须存储一个大于 产品总数/8

          • 您所描述的是一个非常糟糕的组合问题:对于每个选定的类别,迭代每个配方,然后迭代该配方的类别,然后返回该类别的配方计数。即使使用优化的SQL,您也在谈论嵌套的子选择,从逻辑上讲,这不能在指数时间内完成。(这意味着,当你得到很多食谱时,这将非常有害。)随着可能的组合数等于(类别)^2,缓存也变得越来越不切实际

            你确定你必须这样做吗?顺便说一句,你对亚马逊的看法是错误的;他们没有这样的“交叉类别视图”。它们显示搜索命中数,这很容易使用搜索索引。在搜索框中输入“软件”并不是将软件视为一个类别;它把它当作一个关键词

            如果没有人要求这个功能,我建议简化它。在类别过滤器视图中,只需显示匹配的所有配方。在每个菜谱页面上,您可以显示该菜谱所属的所有类别的边栏列表,以及这些类别的计数