Skip to content

Commit

Permalink
Passing aggregation options to the map/reduce ruby driver
Browse files Browse the repository at this point in the history
  • Loading branch information
andresf committed Feb 14, 2012
1 parent 6e261a2 commit 9c67bd0
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
13 changes: 10 additions & 3 deletions lib/mongoid/taggable.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2010 Wilker Lúcio <[email protected]>
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -17,7 +18,7 @@ module Mongoid::Taggable

included do
class_attribute :tags_field, :tags_separator, :tag_aggregation,
:instance_writer => false
:tag_aggregation_options, :instance_writer => false

delegate :convert_string_tags_to_array, :aggregate_tags!, :aggregate_tags?,
:to => 'self.class'
Expand All @@ -38,7 +39,8 @@ module ClassMethods
# class Article
# include Mongoid::Document
# include Mongoid::Taggable
# taggable :keywords, :separator => ' ', :aggregation => true
# taggable :keywords, :separator => ' ', :aggregation => true,
# :aggregation_options => {}
# end
#
# @param [ Symbol ] field The name of the field for tags.
Expand All @@ -49,12 +51,15 @@ module ClassMethods
# @option options [ true, false ] :aggregation Whether or not to
# aggregate counts of tags within the document collection using
# map/reduce; defaults to false
# @option options [ Hash ] :aggregation_options Options for the
# map/reduce ruby-driver method; defaults to {}
def taggable(*args)
options = args.extract_options!

self.tags_field = args.blank? ? :tags : args.shift
self.tags_separator = options.delete(:separator) { ',' }
self.tag_aggregation = options.delete(:aggregation) { false }
self.tag_aggregation_options = options.delete(:aggregation_options) { {} }

field tags_field, options.merge(:type => Array)
index tags_field
Expand Down Expand Up @@ -110,7 +115,9 @@ def aggregate_tags!
return count;
}"

collection.master.map_reduce(map, reduce, :out => tags_aggregation_collection)
map_reduce_options = { :out => tags_aggregation_collection }.
merge(tag_aggregation_options)
collection.master.map_reduce(map, reduce, map_reduce_options)
end

private
Expand Down
32 changes: 31 additions & 1 deletion spec/mongoid/taggable_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2010 Wilker Lúcio <[email protected]>
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -39,7 +40,16 @@ class Template
include Mongoid::Taggable
include Mongoid::Timestamps

taggable :aggregation => true
taggable :aggregation => true
end

class Post
include Mongoid::Document
include Mongoid::Taggable

field :published, :type => Boolean

taggable :aggregation_options => {}
end

describe Mongoid::Taggable do
Expand Down Expand Up @@ -207,6 +217,26 @@ class Template
Article.keywords_with_weight.should include(['tags', 2])
end
end

context "with aggregation options" do
let!(:posts) do
[
Post.create!(:tags => "programming", :published => false),
Post.create!(:tags => "sports,leisure", :published => true),
Post.create!(:tags => "programming, sports", :published => true)
]
end

it "counts aggregates with the specified options" do
Post.tag_aggregation_options = { :query => { :published => true } }
Post.aggregate_tags!
Post.tags_with_weight.should == [
['leisure', 1],
['programming', 1],
['sports', 2],
]
end
end
end

context "#self.tagged_with" do
Expand Down

0 comments on commit 9c67bd0

Please sign in to comment.