Class: Cubicle::Aggregation::AggregationMetadata

Inherits:
Object
  • Object
show all
Defined in:
lib/cubicle/aggregation/aggregation_metadata.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cubicle_metadata, member_names_or_attribute_hash) ⇒ AggregationMetadata

Returns a new instance of AggregationMetadata.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 37

def initialize(,member_names_or_attribute_hash)
  @cubicle_metadata = 
  if (member_names_or_attribute_hash.kind_of?(Hash))
    @attributes = member_names_or_attribute_hash
  else
    member_names = member_names_or_attribute_hash
    @candidate_aggregation = self.class.collection.find(
            :aggregation=>@cubicle_metadata.aggregation.name,
            :member_names=>{"$all"=>member_names}, :document_count=>{"$gte"=>0}).sort([:document_count, :asc]).limit(1).next_document


    #since the operator used in the query was $all, having equal lengths in the original and returned
    #member array means that they are identical, which means that regardless of the number of documents
    #in the aggregation, it is the candidate we want. Otherwise, we'll check to see if we
    #boil down the data further, or just make our soup with what we've got.
    @attributes = @candidate_aggregation if @candidate_aggregation &&
            (@candidate_aggregation["member_names"].length == member_names.length ||
                    @candidate_aggregation["document_count"] < self.class.min_records_to_reduce)

    unless @attributes
      @attributes = HashWithIndifferentAccess.new({:aggregation=>@cubicle_metadata.aggregation.name,
                                                   :member_names=>member_names,
                                                   :document_count=>-1,
                                                   :created_at=>Time.now.utc})

      #materialize the aggregation, and, if the operation was successful,
      #register it as available for use by future queries
      @attributes[:_id] = self.class.collection.insert(@attributes)
      materialize!
    end

  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 103

def method_missing(sym,*args)
  if (@attributes.keys.include?(sym.to_s))
    @attributes[sym.to_s]
  else
    super(sym,*args)
  end
end

Class Method Details

.collectionObject



6
7
8
9
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 6

def collection
  @@aggregations_collection_name ||= "#{Cubicle::Aggregation::CubicleMetadata.collection.name}.aggregations"
  Cubicle.mongo.database[@@aggregations_collection_name]
end

.collection=(collection_name) ⇒ Object



11
12
13
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 11

def collection=(collection_name)
  @@aggregations_collection_name = collection_name
end

.expire(aggregation) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 23

def expire(aggregation)
  aggregation_name = case aggregation
    when String then aggregation
    when Symbol then aggregation.to_s
    when Cubicle::Aggregation::CubicleMetadata then aggregation.aggregation.name
    else aggregation.name
  end
  Cubicle.mongo.database.collection_names.each do |col|
    Cubicle.mongo.database[col].drop if col =~ /cubicle.aggregation.#{aggregation_name}._*/i
    collection.remove(:aggregation=>aggregation_name)
  end
end

.min_records_to_reduceObject



15
16
17
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 15

def min_records_to_reduce
  @min_records_to_reduce ||= 100
end

.min_records_to_reduce=(min) ⇒ Object



19
20
21
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 19

def min_records_to_reduce=(min)
  @min_records_to_reduce = min
end

Instance Method Details

#collectionObject



91
92
93
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 91

def collection
  @collection ||= Cubicle.mongo.database[target_collection_name] if materialized?
end

#collection=(collection) ⇒ Object



95
96
97
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 95

def collection=(collection)
  @collection = collection
end

#document_countObject



99
100
101
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 99

def document_count
  @attributes["document_count"]
end

#materialized?Boolean

Returns:

  • (Boolean)


85
86
87
88
89
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 85

def materialized?
  document_count >= 0 &&
  (!@collection.blank? ||
   Cubicle.mongo.database.collection_names.include?(target_collection_name))
end

#member_namesObject



83
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 83

def member_names; @attributes["member_names"] || []; end

#source_collection_nameObject



75
76
77
78
79
80
81
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 75

def source_collection_name
  if @candidate_aggregation
    candidate = Cubicle::Aggregation::AggregationMetadata.new(@cubicle_metadata,@candidate_aggregation)
    return candidate.target_collection_name
  end
  @cubicle_metadata.aggregation.target_collection_name
end

#target_collection_nameObject



71
72
73
# File 'lib/cubicle/aggregation/aggregation_metadata.rb', line 71

def target_collection_name
  "cubicle.aggregation.#{@cubicle_metadata.aggregation.name}._#{@attributes["_id"].to_s}"
end