Class: MarkLogic::Collection

Inherits:
Object
  • Object
show all
Defined in:
lib/marklogic/collection.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, database) ⇒ Collection

Returns a new instance of Collection.


10
11
12
13
14
# File 'lib/marklogic/collection.rb', line 10

def initialize(name, database)
  @collection = name
  @database = database
  @operators = %w{GT LT GE LE EQ NE ASC DESC}
end

Instance Attribute Details

#collectionObject Also known as: name

Returns the value of attribute collection


6
7
8
# File 'lib/marklogic/collection.rb', line 6

def collection
  @collection
end

#databaseObject (readonly)

Returns the value of attribute database


7
8
9
# File 'lib/marklogic/collection.rb', line 7

def database
  @database
end

Instance Method Details

#build_query(name, operator, value, query_options = {}) ⇒ Object


132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/marklogic/collection.rb', line 132

def build_query(name, operator, value, query_options = {})
  if database.has_range_index?(name) && (query_options.has_key?(:case_sensitive) == false || query_options[:case_sensitive] == true)
    index = database.range_index(name)
    type = index.scalar_type
    Queries::RangeQuery.new(name, operator, type, value, query_options)
  elsif operator != 'EQ'
    raise MissingIndexError.new("Missing index on #{name}")
  elsif value.nil?
    Queries::OrQuery.new([
      Queries::ValueQuery.new(name, value, query_options),
      Queries::NotQuery.new(Queries::ContainerQuery.new(name, Queries::AndQuery.new))
    ])
  elsif operator == 'EQ'
    Queries::ValueQuery.new(name, value, query_options)
  end
end

#countObject


16
17
18
# File 'lib/marklogic/collection.rb', line 16

def count
  MarkLogic::Cursor.new(self).count
end

#dropObject

Raises:

  • (Exception)

104
105
106
107
108
# File 'lib/marklogic/collection.rb', line 104

def drop
  url = "/v1/search?collection=#{collection}"
  response =@database.connection.delete(url)
  raise Exception.new("Invalid response: #{response.code.to_i}, #{response.body}") unless [204].include? response.code.to_i
end

#find(query = nil, options = {}) ⇒ Object


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/marklogic/collection.rb', line 115

def find(query = nil, options = {})
  if query.class == Hash
    query = from_criteria(query)
  elsif query.nil?
    query = Queries::AndQuery.new()
  end
  options[:query] = query
  cursor = MarkLogic::Cursor.new(self, options)

  if block_given?
    yield cursor
    nil
  else
    cursor
  end
end

#find_one(query = nil, options = {}) ⇒ Object


110
111
112
113
# File 'lib/marklogic/collection.rb', line 110

def find_one(query = nil, options = {})
  opts = options.merge(:per_page => 1)
  find(query, opts).next
end

#from_criteria(criteria) ⇒ Object

Builds a MarkLogic Query from Mongo Style Criteria

Examples:

Build a query from criteria


# Query on age == 3
collection.from_criteria({ 'age' => { '$eq' =>  3  } })

# Query on age < 3
collection.from_criteria({ 'age' => { '$lt' =>  3  } })

# Query on age <= 3
collection.from_criteria({ 'age' => { '$le' =>  3  } })

# Query on age > 3
collection.from_criteria({ 'age' => { '$gt' =>  3  } })

# Query on age >= 3
collection.from_criteria({ 'age' => { '$ge' =>  3  } })

# Query on age != 3
collection.from_criteria({ 'age' => { '$ne' =>  3  } })

Parameters:

  • criteria (Hash)

    The Criteria to use when searching

Since:

  • 0.0.1


174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/marklogic/collection.rb', line 174

def from_criteria(criteria)
  queries = []

  criteria.each do |k, v|
    name, operator, index_type, value = nil
    query_options = {}

    if (v.is_a?(Hash))
      name = k.to_s
      query_options.merge!(v.delete(:options) || {})

      sub_queries = []
      v.each do |kk, vv|
        operator = kk.to_s.gsub('$', '').upcase || "EQ"
        if @operators.include?(operator)
          value = vv
          value = value.to_s if value.is_a?(MarkLogic::ObjectId)
          sub_queries << build_query(name, operator, value, query_options)
        elsif value.is_a?(Hash)
          child_queries = value.map do |kk, vv|
            build_query(kk, vv, query_options)
          end
          sub_queries << Queries::ContainerQuery.new(name, Queries::AndQuery.new(child_queries))
        end
      end

      if sub_queries.length > 1
        queries << Queries::AndQuery.new(sub_queries)
      elsif sub_queries.length == 1
        queries << sub_queries[0]
      end
    else
      name = k.to_s
      value = v
      operator = "EQ"
      queries << build_query(name, operator, value, query_options)
    end
  end

  if queries.length > 1
    MarkLogic::Queries::AndQuery.new(*queries)
  elsif queries.length == 1
    queries[0]
  end
end

#inspectObject


224
225
226
227
228
229
230
# File 'lib/marklogic/collection.rb', line 224

def inspect
  as_nice_string = [
    " collection: #{collection.inspect}",
    " database: #{database.database_name.inspect}"
  ].join(",")
  "#<#{self.class}#{as_nice_string}>"
end

#load(id) ⇒ Object

Raises:

  • (Exception)

20
21
22
23
24
25
# File 'lib/marklogic/collection.rb', line 20

def load(id)
  url = "/v1/documents?uri=#{gen_uri(id)}&format=json"
  response = @database.connection.get(url)
  raise Exception.new("Invalid response: #{response.code.to_i}, #{response.body}") unless response.code.to_i == 200
  Oj.load(response.body)
end

#remove(query = nil, options = {}) ⇒ Object


88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/marklogic/collection.rb', line 88

def remove(query = nil, options = {})
  if query.nil? || (query.is_a?(Hash) && query.empty?)
    drop
  else
    if query.class == Hash
      query = from_criteria(query)
    elsif query.nil?
      query = Queries::AndQuery.new()
    end

    xqy = %Q{cts:search(fn:collection("#{collection}"), #{query.to_xqy}, ("unfiltered")) / xdmp:node-delete(.)}
    response = @database.connection.run_query(xqy, "xquery")
    raise Exception.new("Invalid response: #{response.code.to_i}, #{response.body}") unless response.code.to_i == 200
  end
end

#save(doc) ⇒ Object Also known as: create, insert


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/marklogic/collection.rb', line 27

def save(doc)
  if (doc.is_a?(Array))
    docs = {}
    doc.each do |d|
      docs[doc_uri(d)] = ::Oj.dump(d, mode: :compat)
    end
    body = build_multipart_body(docs)
    response = @database.connection.post_multipart("/v1/documents", body)
    raise Exception.new("Invalid response: #{response.code.to_i}, #{response.body}\n") unless response.code.to_i == 200
  else
    uri = doc_uri(doc)
    url = "/v1/documents?uri=#{uri}&format=json&collection=#{collection}"
    json = ::Oj.dump(doc, mode: :compat)
    response = @database.connection.put(url, json)
    raise Exception.new("Invalid response: #{response.code.to_i}, #{response.body}\n") unless [201, 204].include? response.code.to_i
    doc[:_id] || doc[:id] || doc['_id'] || doc['id']
  end
end

#to_sObject


220
221
222
# File 'lib/marklogic/collection.rb', line 220

def to_s
  %Q{collection: #{collection}}
end

#update(selector, document, opts = {}) ⇒ Object


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/marklogic/collection.rb', line 46

def update(selector, document, opts={})
  find(selector).each do |doc|
    document.each do |key, value|
      case key
      when "$set"
        value.each do |kk, vv|
          doc[kk.to_s] = vv
        end
      when "$inc"
        value.each do |kk, vv|
          prev = doc[kk.to_s] || 0
          doc[kk.to_s] = prev + vv
        end
      when "$unset"
        value.keys.each do |kk|
          doc.delete(kk.to_s)
        end
      when "$push"
        value.each do |kk, vv|
          if doc.has_key?(kk.to_s)
            doc[kk.to_s].push(vv)
          else
            doc[kk.to_s] = [vv]
          end
        end
      when "$pushAll"
        value.each do |kk, vv|
          if doc.has_key?(kk.to_s)
            doc[kk.to_s] = doc[kk.to_s] + vv
          else
            doc[kk.to_s] = vv
          end
        end
      end
      save(doc)
    end
  end
end