2012-02-10 3 views
0

Я разрабатываю веб-приложение с помощью Codeigniter и MongoDB. Я пытаюсь заставить карту свести к работе.Сводка для подсчета меток

У меня есть файл с нижерасположенной структурой. Я хотел бы сделать карту уменьшить до проверить, сколько раз каждый тег используется и выводить его в коллекцию files.tags.

{ 
    "_id": { 
     "$id": "4f26f21f09ab66c1030d0000e" 
    }, 
    "basic": { 
     "name": "The filename" 
    }, 
    "tags": [ 
     "lorry", 
     "house", 
     "car", 
     "bicycle" 
    ], 
    "updated_at": "2012-02-09 11:08:03" 
} 

Я попробовал эту карту сократить команду, но это не считается каждый отдельный тег:

$map = new MongoCode ("function() { 

emit({tags: this.tags}, {count: 1}); 

}"); 

    $reduce = new MongoCode ("function(key , values) { 

    var count = 0; 

    values.forEach(function(v) { 
     count += v['count']; 
    }); 

    return {count: count}; 

    }"); 

    $this->mongo_db->command (array (

    "mapreduce" => "files", 
    "map"  => $map, 
    "reduce" => $reduce, 
    "out"  => "files.tags" 

    ) 

    ); 

ответ

1

Да, эта карта/Reduce просто вычислить общее количество тегов.

В mongodb cookbook there is example вы ищете.

Вы должны излучать каждый тег вместо всей коллекции тегов:

map = function() { 
    if (!this.tags) { 
     return; 
    } 

    for (index in this.tags) { 
     emit(this.tags[index], 1); 
    } 
} 
+0

Работал отлично! Прямо сейчас каждый документ в files.tags получает _ID из имени тега. Я хотел бы предоставить каждому документу обычный MongoId, а затем добавить тег: «thetag» для каждого документа. Как я могу это сделать? –

+0

@JonathanClark: из моей практики сокращение карты всегда медленное, и я стараюсь избегать этого. Или, если это действительно необходимо, я перехожу к фоновому асинхронному процессу или использую [incremental] (http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-MongoShellScriptwithIncrementalMapReduceandFinalize). Map/reduce быстрее, потому что он работает с не полным источник данных. Таким образом, общая карта/сокращение неприемлема для расчетов в реальном времени, особенно с большими объемами данных. –

+0

Да, это печально. Вы знаете, как использовать обычные MongoIds вместо того, чтобы устанавливать _id в имя тега? И вместо этого добавьте имя тега в документ? –

1

Вам нужно вызвать испускают один раз для каждого тега во входных документах.

MongoDB документации, например, говорит:

карта вызовы функций испускают (ключ, значение) любое число раз, чтобы кормить данные к редуктору. В большинстве случаев вы будете испускать один раз на входной документ, но в некоторых случаях, таких как подсчет тегов, , данный документ может иметь один, много или даже нулевые теги.

+0

Если бы я получил 1.000.000 документы в коллекции файлов с 5 тегов для каждого будет Карта уменьшить еще быть быстрым? –

+0

это, вероятно, займет около 10 минут, я верю. Что вы определяете как быстро? – ggreiner

+0

А, ок. Я просто хотел почувствовать это. Возможно, лучше обновить счетчик тегов, когда пользователь создает новый файл? –

1

Изменения функции Карты для:

function map(){ 
    if(!this.tags) return; 
    this.tags.forEach(function(tag){ 
     emit(tag, {count: 1}); 
    }); 
} 
Смежные вопросы