Skip to content

Commit

Permalink
Refactoring aggregates in order to support aggregate each [#72 state:…
Browse files Browse the repository at this point in the history
…open]
  • Loading branch information
andreas committed Sep 28, 2009
1 parent 31fdb51 commit 1c0ab81
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 144 deletions.
7 changes: 6 additions & 1 deletion lib/neo4j/extensions/aggregate.rb
Expand Up @@ -3,6 +3,11 @@
require 'neo4j/extensions/aggregate/group_enum'
require 'neo4j/extensions/aggregate/group_node'
require 'neo4j/extensions/aggregate/property_enum'
require 'neo4j/extensions/aggregate/node_mixin'
require 'neo4j/extensions/aggregate/aggregate_node_mixin'
require 'neo4j/extensions/aggregate/aggregate_node'
require 'neo4j/extensions/aggregate/ext/node_mixin'

require 'neo4j/extensions/aggregate/aggregator_each'
require 'neo4j/extensions/aggregate/group_each_node'
require 'neo4j/extensions/aggregate/aggregate_each_node_mixin'
require 'neo4j/extensions/aggregate/aggregate_each_node'
6 changes: 6 additions & 0 deletions lib/neo4j/extensions/aggregate/aggregate_each_node.rb
@@ -0,0 +1,6 @@
module Neo4j::Aggregate
class AggregateEachNode
include Neo4j::NodeMixin
include Neo4j::Aggregate::AggregateEachNodeMixin
end
end
22 changes: 22 additions & 0 deletions lib/neo4j/extensions/aggregate/aggregate_each_node_mixin.rb
@@ -0,0 +1,22 @@
module Neo4j::Aggregate

module AggregateEachNodeMixin
include Neo4j::NodeMixin
include Enumerable

has_list :groups

def aggregate_size
groups.size
end

def each
groups.each {|node| yield node}
end

def aggregate_each(nodes)
AggregatorEach.new(self, nodes)
end
end

end
9 changes: 9 additions & 0 deletions lib/neo4j/extensions/aggregate/aggregate_node.rb
@@ -0,0 +1,9 @@
module Neo4j::Aggregate

class AggregateNode
include Neo4j::NodeMixin
include Neo4j::Aggregate::AggregateNodeMixin
end


end
Expand Up @@ -11,22 +11,11 @@ module Neo4j::Aggregate
#
# This mixin includes the Enumerable mixin.
#
# ==== Example - use the mixin
#
# Example how to create your own class that will provide aggregation of nodes.
#
# class MyAggregatedNode
# include Neo4j::NodeMixin
# include Neo4j::Aggregate::NodeMixin
# end
#
# This class can create group nodes that will be connected as outgoing relationships from it.
#
# ==== Example - group by one property
#
# Let say we have nodes with properties :colour and we want to group them by colour:
#
# a = MyAggregatedNode.new
# a = AggregateNode.new
#
# a.aggregate(nodes).group_by(:colour)
#
Expand Down Expand Up @@ -56,7 +45,7 @@ module Neo4j::Aggregate
# Let say way want to have group which include a range of values.
# Example - group by an age range, 0-4, 5-9, 10-14 etc...
#
# a = MyAggregatedNode.new
# a = AggregateNode.new
# a.aggregate(an enumeration of nodes).group_by(:age).of_value{|age| age / 5}
#
# # traverse all people in age group 10-14 (3 maps to range 10-14)
Expand Down Expand Up @@ -95,7 +84,7 @@ module Neo4j::Aggregate
# The aggregate node mixin implements the << operator that allows you to append nodes to the aggregate and the
# appended node will be put in the correct group.
#
# a = MyAggregatedNode.new
# a = AggregateNode.new
# a.aggregate.group_by(:age).of_value{|age| age / 5}
#
# a << node1 << node2
Expand Down Expand Up @@ -130,11 +119,11 @@ module Neo4j::Aggregate
#
# ==== Example - aggregating over another aggregation
#
# a = MyAggregatedNode.new
# a = AggregateNode.new
# a.aggregate.group_by(:colour)
# a << node1 << node2
#
# b = MyAggregatedNode.new
# b = AggregateNode.new
# b.aggregate.group_by(:age)
# node3[:colour] = 'green'; node3[:age] = 10
# node4[:colour] = 'red'; node3[:age] = 11
Expand All @@ -152,7 +141,7 @@ module Neo4j::Aggregate
# This is done by registering the aggregate dsl method as an event listener
#
# Here is an example that update the aggregate a on all nodes of type MyNode
# a = MyAggregatedNode.new
# a = AggregateNode.new
#
# # the aggreate will get notified when nodes of type MyNode get changed
# a.aggregate(MyNode).group_by(:colour)
Expand Down Expand Up @@ -242,7 +231,7 @@ module Neo4j::Aggregate
# a[:rev] => ["good", "good", "bad"]
# a[:rev]["good"] => 2
# a[:rev]["bad"] => 1
module NodeMixin
module AggregateNodeMixin
include Neo4j::NodeMixin
property :aggregate_size # number of groups this aggregate contains
include Enumerable
Expand Down
29 changes: 29 additions & 0 deletions lib/neo4j/extensions/aggregate/aggregator_each.rb
@@ -0,0 +1,29 @@
module Neo4j::Aggregate
class AggregatorEach
def initialize(root_node, nodes)
@root_node = root_node
@nodes = nodes
end

# Specifies which properties we should group on.
# All thos properties can be combined to create a new group.
#
# :api: public
def group_by(*keys)
@group_by = keys
self
end


def execute
@nodes.each do |node|
puts "agg #{node}"
group_node = GroupEachNode.new
group_node.group_by = @group_by.join(',')
group_node.aggregate = node
@root_node.groups << group_node
puts "agg #{node} done"
end
end
end
end
31 changes: 31 additions & 0 deletions lib/neo4j/extensions/aggregate/group_each_node.rb
@@ -0,0 +1,31 @@
module Neo4j::Aggregate

class GroupEachNode
include Neo4j::NodeMixin
include Enumerable

has_one :aggregate
property :aggregate_group, :aggregate_size, :group_by


def each
puts "each group #{group_by}"
puts "Agg node #{aggregate.props.inspect}"
group_by.split(',').each do |group|
puts "VALUE key='#{group}' vakye=#{aggregate[group]}'"
yield aggregate[group]
end
end


# :api: private
def get_property(key)
value = super(key)
return value unless value.nil?
return nil unless aggregate
aggregate[key]
end

end

end

0 comments on commit 1c0ab81

Please sign in to comment.