<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -185,7 +185,7 @@ module Neo4j::Aggregate
       # check if it is the leaf node or not
       if (@child_dsl)
         # this is not the leaf aggregate dsl, let the child node add the node instead
-        @child_dsl.create_groups(group_node, node)  # TODO
+        @child_dsl.create_groups(group_node, node)  
       else
         # this IS a leaf aggregate dsl, add node to the group
         rel_type = node.kind_of?(AggregateGroupNode)? key : :aggregate</diff>
      <filename>lib/neo4j/extensions/aggregate/aggregator.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,6 @@ module Neo4j::Aggregate
         Neo4j.event_handler.add(self)
         @filter = nodes_or_class
       end
-      puts &quot;init aggregate_each root #{root_node.neo_node_id}&quot;      
       @root_node = root_node
       @nodes = nodes_or_class
     end
@@ -34,8 +33,6 @@ module Neo4j::Aggregate
       return if node.class != @filter
       return unless @group_by.include?(prop_key.to_sym)
 
-      puts &quot;on_property_changed node: #{node.neo_node_id} prop: #{prop_key} old: #{old_value} new: #{new_value}&quot;
-
       # for each aggregate the node belongs to delete it
       # we have to first create it and then deleted, otherwise cascade delete will kick in
       group = node.aggregate_groups(@root_node.aggregate_id)
@@ -45,15 +42,6 @@ module Neo4j::Aggregate
 
       # delete this aggregate group if it exists
       group.delete if group
-
-#      puts &quot;EXIT NODE CHANGED ====&quot;
-#      puts &quot;OUTGOING NODE&quot;
-#      node.print 3, :outgoing
-#      puts &quot;INCOMING NODE&quot;
-#      node.print 3, :incoming
-#
-#      puts &quot;ROOT NODE, OUTGOING&quot;
-      @root_node.print 3, :outgoing
     end
 
     # Specifies which properties we should group on.
@@ -65,6 +53,10 @@ module Neo4j::Aggregate
       self
     end
 
+    def with(prop_key, &amp;proc)
+      @with_proc = proc
+      @prop_key = prop_key
+    end
 
     def execute(nodes = @nodes)
       return unless nodes
@@ -72,13 +64,13 @@ module Neo4j::Aggregate
         group_node = GroupEachNode.new
         group_node.group_by = @group_by.join(',')
         group_node.aggregate = node
-        puts &quot;  create rel between #{node.neo_node_id} and group_node #{group_node.neo_node_id}&quot;
         rel = group_node.relationships.outgoing(:aggregate)[node]
-        puts &quot;    found rel #{rel.neo_relationship_id}  agg_id: #{@root_node.aggregate_id.to_s} start: #{rel.start_node.neo_node_id}, end: #{rel.end_node.neo_node_id}&quot;
         rel[:aggregate_group] = @root_node.aggregate_id.to_s
         @root_node.groups &lt;&lt; group_node
-        puts &quot;    created rel between root #{@root_node.neo_node_id} and #{group_node.neo_node_id}&quot;
-#        group_node.print 3, :both
+        if @with_proc
+          val = group_node.inject(0) {|sum, val| next sum if val.nil?; @with_proc.call(sum, val, 0)}
+          group_node[@prop_key.to_s] = val
+        end
       end
       @nodes = nil # prevent it to run twice
     end</diff>
      <filename>lib/neo4j/extensions/aggregate/aggregator_each.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,14 +8,18 @@ require 'neo4j/spec_helper'
 
 AggregateEachNode = Neo4j::Aggregate::AggregateEachNode
 
-describe &quot;Aggregate Each&quot; do
+describe &quot;Aggregate each node&quot; do
   before(:all) do
     class Company
       include Neo4j::NodeMixin
       property :month, :revenue
     end
   end
-  
+
+  after(:all) do
+    undefine_class :Company
+  end
+
   before(:each) do
     start
     Neo4j::Transaction.new
@@ -27,45 +31,65 @@ describe &quot;Aggregate Each&quot; do
     @registrations.each {|reg| reg.unregister}
   end
 
-  it &quot;should create a new group for each node&quot; do
-    #pending &quot;work in progress&quot;
-    nodes = []
-    4.times {nodes &lt;&lt; Neo4j::Node.new}
-    nodes[0][:colour] = 'red';  nodes[0][:name] = &quot;a&quot;; nodes[0][:age] = 0
-    nodes[1][:colour] = 'red';  nodes[1][:name] = &quot;b&quot;; nodes[1][:age] = 1
-    nodes[2][:colour] = 'red';  nodes[2][:name] = &quot;c&quot;; nodes[2][:age] = 2
-    nodes[3][:colour] = 'blue'; nodes[3][:name] = &quot;d&quot;; nodes[3][:age] = 3
+  describe &quot;Access aggregated node properties&quot; do
+    before(:each) do
+#      Neo4j::Transaction.new
+      @nodes = []
+      4.times {@nodes &lt;&lt; Neo4j::Node.new}
+      @nodes[0][:colour] = 'red';  @nodes[0][:name] = &quot;a&quot;;  @nodes[0][:age] = 0
+      @nodes[1][:colour] = 'red';  @nodes[1][:name] = &quot;b&quot;;  @nodes[1][:age] = 1
+      @nodes[2][:colour] = 'red';  @nodes[2][:name] = &quot;c&quot;;  @nodes[2][:age] = 2
+      @nodes[3][:colour] = 'blue'; @nodes[3][:name] = &quot;d&quot;;  @nodes[3][:age] = 3
+
+      # when
+      @aggregate_node = AggregateEachNode.new
+      @aggregate_node.aggregate_each(@nodes).group_by(:colour, :name).execute
+    end
 
+    it &quot;can be retrieved as a group Neo4j::NodeMixin#aggregate_groups&quot; do
+            Neo4j::Transaction.new
+      # then we should have one group
+      @nodes[0].aggregate_groups.to_a.size.should == 1
+      group = @nodes[0].aggregate_groups.to_a[0]
 
-    agg1 = AggregateEachNode.new
+      # and that group should contain the node property values
+      group.should include('red', 'a')
+      group.to_a.size.should == 2
+      group[:age].should == 0 # group for @nodes[0]
+    end
 
-    # when
-    agg1.aggregate_each(nodes).group_by(:colour, :name).execute
+    it &quot;can all be retrieved from the aggregate node&quot; do
+      # there are total 8 property values
+      @aggregate_node.to_a.sort.should == [&quot;blue&quot;, &quot;d&quot;, &quot;red&quot;, &quot;c&quot;, &quot;red&quot;, &quot;b&quot;, &quot;red&quot;, &quot;a&quot;].sort
+    end
 
-    # then
-    nodes[0].aggregate_groups.to_a.size.should == 1
-    g1 = nodes[0].aggregate_groups.to_a[0]
-    g1.should include('red', 'a')
-    g1.to_a.size.should == 2
-    g1[:age].should == 0 # group for @nodes[0]
+    it &quot;can be retrieved from the aggregate node as an group&quot; do
+      # there are total 4 groups
+      @aggregate_node.aggregate_size.should == 4
 
-    agg1.to_a.sort.should == [&quot;blue&quot;, &quot;d&quot;, &quot;red&quot;, &quot;c&quot;, &quot;red&quot;, &quot;b&quot;, &quot;red&quot;, &quot;a&quot;].sort
-    agg1.to_a.size.should == 8
-    agg1.aggregate_size.should == 4
+      # so that we know which group is which group we put it in a age_groups map
+      age_groups = {}
+      @aggregate_node.groups.each {|g| age_groups[g[:age]] = g}
+
+      age_groups[3].should include('blue','d')
+      age_groups[0].should include('red','a')
+    end
   end
 
   it &quot;should delete group if the node is deleted&quot; do
     nodes = []
     4.times {nodes &lt;&lt; Neo4j::Node.new}
-    nodes[0][:colour] = 'red';  nodes[0][:name] = &quot;a&quot;; nodes[0][:age] = 0
-    nodes[1][:colour] = 'red';  nodes[1][:name] = &quot;b&quot;; nodes[1][:age] = 1
-    nodes[2][:colour] = 'red';  nodes[2][:name] = &quot;c&quot;; nodes[2][:age] = 2
+    nodes[0][:colour] = 'red'; nodes[0][:name] = &quot;a&quot;; nodes[0][:age] = 0
+    nodes[1][:colour] = 'red'; nodes[1][:name] = &quot;b&quot;; nodes[1][:age] = 1
+    nodes[2][:colour] = 'red'; nodes[2][:name] = &quot;c&quot;; nodes[2][:age] = 2
     nodes[3][:colour] = 'blue'; nodes[3][:name] = &quot;d&quot;; nodes[3][:age] = 3
 
     agg1 = AggregateEachNode.new
     agg1.aggregate_each(nodes).group_by(:colour, :name)
     agg1.to_a.size.should == 8
     agg1.aggregate_size.should == 4
+    agg1.groups.size.should == 4
+
 
     # when
     n = nodes[2].aggregate_groups.to_a[0]
@@ -83,7 +107,7 @@ describe &quot;Aggregate Each&quot; do
   it &quot;should create new groups for each node, group by quarter&quot; do
     revenue1 = Neo4j::Node.new
     revenue2 = Neo4j::Node.new
-    revenue1[:jan] = 1;  revenue1[:feb] = 2;  revenue1[:mars] = 3;  revenue1[:april] = 4;  revenue1[:may] = 5;  revenue1[:june] = 6
+    revenue1[:jan] = 1; revenue1[:feb] = 2; revenue1[:mars] = 3; revenue1[:april] = 4; revenue1[:may] = 5; revenue1[:june] = 6
     revenue2[:jan] = 11; revenue2[:feb] = 12; revenue2[:mars] = 13; revenue2[:april] = 14; revenue2[:may] = 15; revenue2[:june] = 16
 
     # when
@@ -96,8 +120,8 @@ describe &quot;Aggregate Each&quot; do
     # then there should be two groups, one for each revenue node
     q1.aggregate_size.should == 2
     # with each 3 values, total 6 (2*3)
-    q1.to_a.sort.should == [1,2,3,11,12,13]
-    q2.to_a.sort.should == [4,5,6,14,15,16]
+    q1.to_a.sort.should == [1, 2, 3, 11, 12, 13]
+    q2.to_a.sort.should == [4, 5, 6, 14, 15, 16]
   end
 
 
@@ -107,29 +131,29 @@ describe &quot;Aggregate Each&quot; do
 
     # when
     c1 = Company.new
-    c1[:jan]  = 100
-    c1[:feb]  = 200
+    c1[:jan] = 100
+    c1[:feb] = 200
     c1[:mars] = 300
-    c1[:april]  = 400
-    c1[:may]  = 500
+    c1[:april] = 400
+    c1[:may] = 500
     c1[:june] = 600
 
     c2 = Company.new
-    c2[:jan]  = 1100
-    c2[:feb]  = 1200
+    c2[:jan] = 1100
+    c2[:feb] = 1200
     c2[:mars] = 1300
-    c2[:april]  = 1400
-    c2[:may]  = 1500
+    c2[:april] = 1400
+    c2[:may] = 1500
     c2[:june] = 1600
 
-    q1.aggregate_each([c1,c2]).group_by(:jan, :feb, :mars).execute
-    q2.aggregate_each([c1,c2]).group_by(:april, :may, :june).execute
+    q1.aggregate_each([c1, c2]).group_by(:jan, :feb, :mars).execute
+    q2.aggregate_each([c1, c2]).group_by(:april, :may, :june).execute
 
     # then
     q1.groups.should include(c1.aggregate_groups(:q1))
     q1.groups.should include(c2.aggregate_groups(:q1))
     q2.groups.should include(c1.aggregate_groups(:q2))
-    q2.groups.should include(c2.aggregate_groups(:q2))    
+    q2.groups.should include(c2.aggregate_groups(:q2))
   end
 
   it &quot;should allow to register nodes classes to be part of aggregates&quot; do
@@ -141,24 +165,24 @@ describe &quot;Aggregate Each&quot; do
 
     # when
     c1 = Company.new
-    c1[:jan]  = 100
-    c1[:feb]  = 200
+    c1[:jan] = 100
+    c1[:feb] = 200
     c1[:mars] = 300
-    c1[:april]  = 400
-    c1[:may]  = 500
+    c1[:april] = 400
+    c1[:may] = 500
     c1[:june] = 600
 
     c2 = Company.new
-    c2[:jan]  = 1100
-    c2[:feb]  = 1200
+    c2[:jan] = 1100
+    c2[:feb] = 1200
     c2[:mars] = 1300
-    c2[:april]  = 1400
-    c2[:may]  = 1500
+    c2[:april] = 1400
+    c2[:may] = 1500
     c2[:june] = 1600
 
     # then
-    q1.should include(100,200,300,1100,1200,1300)
-    q2.should include(400,500,600,1400,1500,1600)
+    q1.should include(100, 200, 300, 1100, 1200, 1300)
+    q2.should include(400, 500, 600, 1400, 1500, 1600)
   end
 
   it &quot;should update the aggregate when a node changes&quot; do
@@ -167,9 +191,9 @@ describe &quot;Aggregate Each&quot; do
 
     # given
     c1 = Company.new
-    c1[:jan]  = 100
-    c1[:feb]  = 200
-    q1.should include(100,200)
+    c1[:jan] = 100
+    c1[:feb] = 200
+    q1.should include(100, 200)
 
     # when
     c1[:feb] = 42
@@ -179,65 +203,49 @@ describe &quot;Aggregate Each&quot; do
     q1.should include(42)
   end
 
-  it &quot;should delete the aggregate when the node is deleted&quot; do
+  it &quot;should delete the group when the node is deleted&quot; do
     pending
     q1 = AggregateEachNode.new(:q1)
     @registrations &lt;&lt; q1.aggregate_each(Company).group_by(:jan, :feb, :mars)
 
     # given
     c1 = Company.new
-    c1[:jan]  = 100
-    c1[:feb]  = 200
-    q1.should include(100,200)
+    c1[:jan] = 100
+    c1[:feb] = 200
+    q1.should include(100, 200)
     q1.groups.size.should == 1
     Neo4j.load(q1.neo_node_id).should_not be_nil
 
-    # then
-#    puts &quot;C1, incoming&quot;
-#    c1.print 3, :incoming
-#
-#    puts &quot;C1, outgoing&quot;
-#    c1.print 3, :outgoing
-#
-#    puts &quot;Q1, incoming&quot;
-#    q1.print 3, :incoming
-#
-#    puts &quot;Q1, outgoing&quot;
-#    q1.print 3, :outgoing
-    puts &quot;------------------------&quot;
-    puts &quot;D E L E T E&quot;
-    puts &quot;------------------------&quot;
-    
     # when
     c1.delete
 
     # then
-    puts &quot;Q1------------------&quot;
-    q1.print 2,:both
     q1.groups.size.should == 0
-
     q1.should_not include(100)
     q1.should_not include(200)
   end
-  
+
   it &quot;should allow to register nodes classes to be part of aggregates&quot; do
-    pending
+#    pending
     # given
     q1 = AggregateEachNode.new(:q1)
-    q1.aggregate_each(Company).group_by(:jan, :feb, :mars).with(:sum){|sum,val,prev_val|  sum + val - prev_val}
+    q1.aggregate_each(Company).group_by(:jan, :feb, :mars).with(:sum){|sum, val, prev_val| sum + val - prev_val}
     q2 = AggregateEachNode.new(:q2)
-    q2.aggregate_each(Company).group_by(:april, :may, :june)
+    q2.aggregate_each(Company).group_by(:april, :may, :june).with(:sum){|sum, val, prev_val| sum + val - prev_val}
 
     # when
     c1 = Company.new
-    c1[:jan]  = 100
-    c1[:feb]  = 200
+    c1[:jan] = 100
+    c1[:feb] = 200
     c1[:mars] = 300
-    c1[:april]  = 400
-    c1[:may]  = 500
+    c1[:april] = 400
+    c1[:may] = 500
     c1[:june] = 600
 
     # then
+    puts &quot;C1 GROUP Q1: #{c1.aggregate_groups(:q1).neo_node_id}&quot;
+    puts &quot;C1 GROUP Q2: #{c1.aggregate_groups(:q2).neo_node_id}&quot;
+
     c1.aggregate_groups(:q1)[:sum].should == 100+200+300
     c1.aggregate_groups(:q2)[:sum].should == 400+500+600
   end</diff>
      <filename>test/extensions/aggregate_each_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -190,7 +190,7 @@ describe &quot;Aggregates&quot; do
       agg_root[&quot;bad&quot;].aggregate_size.should == 1
       agg_root[&quot;average&quot;].aggregate_size.should == 2
 
-      # there are two sub groups, one groop with same score 101 and another group with score 102
+      # there are two sub groups, one group with same score 101 and another group with score 102
       agg_root[&quot;good&quot;].aggregate_size.should == 2
 
       agg_root[&quot;good&quot;][101].aggregate_size.should == 2
@@ -280,7 +280,7 @@ describe &quot;Aggregates&quot; do
 
   end
 
-  describe &quot;grouped by one property (colour)&quot; do
+  describe &quot;grouped by one property&quot; do
     # Called before each example.
     before(:each) do
       @red=[]
@@ -336,7 +336,7 @@ describe &quot;Aggregates&quot; do
       names.should include('a', 'b', 'c', 'd')
     end
 
-    it &quot;should not add nodes to the aggreation that does not have a group property&quot; do
+    it &quot;should not add nodes to the aggregation that does not have a group property&quot; do
       # add a node that does not have the colour property
 
       @agg_node.to_a.size.should == 3
@@ -418,7 +418,7 @@ describe &quot;Aggregates&quot; do
     end
 
 
-    it &quot;should have a counter for number of meber in each group&quot; do
+    it &quot;should have a counter for number of member in each group&quot; do
       # Creates age group 0=0-4, 1=5-9, 2=10-14
       @registrations &lt;&lt; @aggregate_node.aggregate(@people).group_by(:age).map_value{|age| age / 5}
 
@@ -562,23 +562,6 @@ describe &quot;Aggregates&quot; do
       # when
       agg_node.include_node?(new_node).should be_true
     end
-
-    it &quot;should not append a node to an aggregate if it already exist in the aggregate&quot; do
-      pending &quot;Not sure if we want that. Will get bad performance if we have to check it each time we add a node to a aggregate&quot;
-      agg_node = AggregateNode.new
-      @registrations &lt;&lt; agg_node.aggregate.group_by(:colour)
-
-      new_node = Neo4j::Node.new
-      new_node[:colour] = 'black'
-
-      # when
-      agg_node &lt;&lt; new_node
-      agg_node &lt;&lt; new_node
-
-      # then
-      agg_node[:black].aggregate_size.should == 1
-      agg_node[:black].should include(new_node)
-    end
   end
 
 </diff>
      <filename>test/extensions/aggregate_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>4de7d5fc2268320550b1d89499df3241f3753106</id>
    </parent>
  </parents>
  <author>
    <name>andreas</name>
    <email>andreas@andreas-xps16.(none)</email>
  </author>
  <url>http://github.com/andreasronge/neo4j/commit/21f4009cee0058a142fe59053fb0a022a6571c01</url>
  <id>21f4009cee0058a142fe59053fb0a022a6571c01</id>
  <committed-date>2009-10-26T15:07:35-07:00</committed-date>
  <authored-date>2009-10-26T15:07:35-07:00</authored-date>
  <message>Impl aggregation function (not very effiecient yet). There is now a DSL for creating things like a sum of the revenue grouped by quarter [#72]
Tidied up some RSpecs</message>
  <tree>fdcf561e07efc5c2c33451d15fbba521da6452f8</tree>
  <committer>
    <name>andreas</name>
    <email>andreas@andreas-xps16.(none)</email>
  </committer>
</commit>
