class Related::Node::Query

Attributes

depth[W]
destination[W]
direction[W]
include_start_node[W]
limit[W]
options[W]
page[W]
relationship_type[W]
result[R]
result_type[W]
search_algorithm[W]

Public Class Methods

new(node) click to toggle source
# File lib/related/node.rb, line 128
def initialize(node)
  @node = node
  @result_type = :nodes
  @depth = 4
  @options = {}
end

Public Instance Methods

as_json(options = {}) click to toggle source
# File lib/related/node.rb, line 207
def as_json(options = {})
  self.to_a
end
count() click to toggle source
# File lib/related/node.rb, line 152
def count
  @count = @result_type == :nodes ?
    Related.redis.scard(key) :
    Related.redis.zcard(key)
  @limit && @count > @limit ? @limit : @count
end
diff(query) click to toggle source
# File lib/related/node.rb, line 195
def diff(query)
  @result_type = :nodes
  @result = Related.redis.sdiff(key, query.key)
  self
end
each(&block) click to toggle source
# File lib/related/node.rb, line 135
def each(&block)
  self.to_a.each(&block)
end
find(node) click to toggle source
# File lib/related/node.rb, line 177
def find(node)
  if @result_type == :nodes
    if Related.redis.sismember(key, node.id)
      node_class.find(node.id, @options)
    end
  else
    if id = Related.redis.get(dir_key(node))
      Related::Relationship.find(id, @options)
    end
  end
end
include?(entity) click to toggle source
# File lib/related/node.rb, line 163
def include?(entity)
  if @destination
    self.to_a.include?(entity)
  else
    if entity.is_a?(node_class)
      @result_type = :nodes
      Related.redis.sismember(key, entity.id)
    elsif entity.is_a?(Related::Relationship)
      @result_type = :relationships
      Related.redis.sismember(key, entity.id)
    end
  end
end
intersect(query) click to toggle source
# File lib/related/node.rb, line 201
def intersect(query)
  @result_type = :nodes
  @result = Related.redis.sinter(key, query.key)
  self
end
map(&block) click to toggle source
# File lib/related/node.rb, line 139
def map(&block)
  self.to_a.map(&block)
end
size() click to toggle source
# File lib/related/node.rb, line 159
def size
  @count || count
end
to_a() click to toggle source
# File lib/related/node.rb, line 143
def to_a
  perform_query unless @result
  if @result_type == :nodes
    node_class.find(@result, @options)
  else
    Related::Relationship.find(@result, @options)
  end
end
to_json(options = {}) click to toggle source
# File lib/related/node.rb, line 211
def to_json(options = {})
  self.as_json.to_json(options)
end
union(query) click to toggle source
# File lib/related/node.rb, line 189
def union(query)
  @result_type = :nodes
  @result = Related.redis.sunion(key, query.key)
  self
end

Protected Instance Methods

depth_first(nodes, depth = 0) click to toggle source
# File lib/related/node.rb, line 276
def depth_first(nodes, depth = 0)
  return [] if depth > @depth
  nodes.each do |node|
    if Related.redis.sismember(key(node), @destination.id)
      return [node, @destination.id]
    else
      res = depth_first(Related.redis.smembers(key(node)), depth+1)
      return [node] + res unless res.empty?
    end
  end
  return []
end
dijkstra(nodes, depth = 0) click to toggle source
# File lib/related/node.rb, line 289
def dijkstra(nodes, depth = 0)
  return [] if depth > @depth
  shortest_path = []
  nodes.each do |node|
    if Related.redis.sismember(key(node), @destination.id)
      return [node, @destination.id]
    else
      res = dijkstra(Related.redis.smembers(key(node)), depth+1)
      if res.size > 0
        res = [node] + res
        if res.size < shortest_path.size || shortest_path.size == 0
          shortest_path = res
        end
      end
    end
  end
  return shortest_path
end
dir_key(node) click to toggle source
# File lib/related/node.rb, line 240
def dir_key(node)
  if @direction == :out
    "#{@node.id}:#{@relationship_type}:#{node.id}"
  elsif @direction == :in
    "#{node.id}:#{@relationship_type}:#{@node.id}"
  end
end
key(node=nil) click to toggle source
# File lib/related/node.rb, line 234
def key(node=nil)
  n = node || @node
  node_id = n.is_a?(String) ? n : n.id
  "#{node_id}:#{@result_type == :nodes ? "n" : "r"}:#{@relationship_type}:#{@direction}"
end
node_class() click to toggle source
# File lib/related/node.rb, line 217
def node_class
  @node.class
end
page_end() click to toggle source
# File lib/related/node.rb, line 230
def page_end
  page_start + @limit.to_i - 1
end
page_start() click to toggle source
# File lib/related/node.rb, line 221
def page_start
  if @page.nil? || @page.to_i.to_s == @page.to_s
    @page && @page.to_i != 1 ? (@page.to_i * @limit.to_i) - @limit.to_i : 0
  else
    rel = @page.is_a?(String) ? Related::Relationship.find(@page) : @page
    rel.rank(@direction) + 1
  end
end
perform_query() click to toggle source
# File lib/related/node.rb, line 252
def perform_query
  @result = []
  if @destination
    @result_type = :nodes
    @result = self.send(@search_algorithm, [@node.id])
    @result.shift unless @include_start_node
    @result
  else
    if @result_type == :nodes
      if @limit
        @result = (1..@limit.to_i).map { Related.redis.srandmember(key) }
      else
        @result = Related.redis.smembers(key)
      end
    else
      if @limit
        @result = Related.redis.zrevrange(key, page_start, page_end)
      else
        @result = Related.redis.zrevrange(key, 0, -1)
      end
    end
  end
end
query() click to toggle source
# File lib/related/node.rb, line 248
def query
  self
end