【问题标题】:Map Reduce To Get Most popular tagsMap Reduce 以获取最受欢迎的标签
【发布时间】:2011-09-20 15:14:17
【问题描述】:

我有一个需要帮助的问题,但我觉得我已经很接近了。它涉及 Lithium 和 MongoDB 代码如下所示: http://pastium.org/view/0403d3e4f560e3f790b32053c71d0f2b

$db = PopularTags::connection();

        $map = new \MongoCode("function() {
            if (!this.saved_terms) {
                return;
            }

            for (index in this.saved_terms) {
                emit(this.saved_terms[index], 1);
            }
        }");

        $reduce = new \MongoCode("function(previous, current) {
            var count = 0;
            for (index in current) {
                count += current[index];
            }
            return count;
            }");

        $metrics = $db->connection->command(array(
           'mapreduce' => 'users',
           'map' => $map,
           'reduce' => $reduce,
           'out' => 'terms'
       ));

        $cursor = $db->connection->selectCollection($metrics['result'])->find()->limit(1);
        print_r($cursor);
/**
User Data In Mongo

{
 "_id" : ObjectId("4e789f954c734cc95b000012"), 
"email" : "example@bob.com", 
 "saved_terms" : [
    null,

    [
        "technology",
        " apple",
        " iphone"
    ],
    [
        "apple",
        " water",
        " beryy"
    ]
] }


**/

我有一个他们搜索的用户储蓄条款,然后我试图获得最流行的条款 但我不断收到错误消息,例如:Uncaught exception 'Exception' with message 'MongoDB::__construct( invalid name '。有人知道如何执行此操作或某个方向吗?

【问题讨论】:

    标签: php mongodb mapreduce lithium nosql


    【解决方案1】:

    首先我不会将它存储在用户对象中。 MongoDb 对象的上限为 4/16MB(取决于版本)。现在这个限制通常不是问题,但是当内联登录一个对象时,您可能能够达到它。然而,一个更现实的问题是,每次您需要对这些对象采取行动时,您都需要将它们加载到 RAM 中,这会变得非常消耗。我认为您不希望在您的用户对象上使用它。

    其次,对象中的数组是不可排序的,并且还有其他限制,以后可能会再次困扰您。

    但是,如果您想要这样(低搜索量真的不是问题),您可以通过使用组查询最轻松地解决这个问题。 组查询非常类似于 sql 中的组查询,因此它是一个小技巧,因为您需要对大多数对象共享的内容进行分组。 (可能是用户的活动字段)。

    因此,这里有一个工作组示例,它将根据您的结构汇总使用的单词。 只需将此方法放入您的模型并执行 MyModel::searchTermUsage() 以获取 Document 对象。

    public static function searchTermUsage() {
        $reduce = 'function(obj, prev) {
            obj.terms.forEach(function(terms) {
                terms.forEach(function(term) {
                    if (!(term in prev)) prev[term] = 0;
                    prev[term]++;
                });
            });
        }';
        return static::all(array(
            'initial' => new \stdclass,
            'reduce' => $reduce,
            'group' => 'common-value-key' // Change this
        ));
    }
    

    terms 字段中没有针对非数组类型的保护(您的示例中有一个空值)。为了简单起见,我删除了它,最好在它最终进入数据库之前将其删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-24
      • 2013-12-10
      • 2020-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-20
      相关资源
      最近更新 更多