gcloud 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/CHANGELOG.md +16 -0
- data/OVERVIEW.md +23 -18
- data/lib/gcloud.rb +41 -27
- data/lib/gcloud/datastore/credentials.rb +1 -1
- data/lib/gcloud/datastore/dataset.rb +2 -0
- data/lib/gcloud/datastore/transaction.rb +9 -2
- data/lib/gcloud/pubsub.rb +34 -0
- data/lib/gcloud/pubsub/service.rb +5 -0
- data/lib/gcloud/translate.rb +236 -0
- data/lib/gcloud/translate/api.rb +248 -0
- data/lib/gcloud/translate/connection.rb +76 -0
- data/lib/gcloud/translate/detection.rb +137 -0
- data/lib/gcloud/{search → translate}/errors.rb +7 -10
- data/lib/gcloud/translate/language.rb +69 -0
- data/lib/gcloud/translate/translation.rb +112 -0
- data/lib/gcloud/version.rb +1 -1
- metadata +9 -17
- data/lib/gcloud/search.rb +0 -318
- data/lib/gcloud/search/api_client.rb +0 -144
- data/lib/gcloud/search/connection.rb +0 -146
- data/lib/gcloud/search/credentials.rb +0 -30
- data/lib/gcloud/search/document.rb +0 -278
- data/lib/gcloud/search/document/list.rb +0 -85
- data/lib/gcloud/search/field_value.rb +0 -158
- data/lib/gcloud/search/field_values.rb +0 -233
- data/lib/gcloud/search/fields.rb +0 -246
- data/lib/gcloud/search/index.rb +0 -572
- data/lib/gcloud/search/index/list.rb +0 -90
- data/lib/gcloud/search/project.rb +0 -181
- data/lib/gcloud/search/result.rb +0 -165
- data/lib/gcloud/search/result/list.rb +0 -95
data/lib/gcloud/search/fields.rb
DELETED
@@ -1,246 +0,0 @@
|
|
1
|
-
# Copyright 2015 Google Inc. All rights reserved.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
|
15
|
-
|
16
|
-
require "gcloud/search/field_values"
|
17
|
-
require "gcloud/search/field_value"
|
18
|
-
|
19
|
-
module Gcloud
|
20
|
-
module Search
|
21
|
-
##
|
22
|
-
# # Fields
|
23
|
-
#
|
24
|
-
# Fields is the object that provides access to a document's fields.
|
25
|
-
#
|
26
|
-
# Each field has a name (String) and a list of values. Each field name
|
27
|
-
# consists of only ASCII characters, must be unique within the document and
|
28
|
-
# is case sensitive. A field name must start with a letter and can contain
|
29
|
-
# letters, digits, or underscore, with a maximum of 500 characters.
|
30
|
-
#
|
31
|
-
# A field can have multiple values with same or different types; however, it
|
32
|
-
# cannot have multiple datetime (DateTime) or number (Float) values. (See
|
33
|
-
# {FieldValues} and {FieldValue})
|
34
|
-
#
|
35
|
-
# @example
|
36
|
-
# require "gcloud"
|
37
|
-
#
|
38
|
-
# gcloud = Gcloud.new
|
39
|
-
# search = gcloud.search
|
40
|
-
# index = search.index "products"
|
41
|
-
#
|
42
|
-
# document = index.document "product-sku-000001"
|
43
|
-
# puts "The document #{document.doc_id} has the following fields:"
|
44
|
-
# document.names.each do |name|
|
45
|
-
# puts "* #{name}:"
|
46
|
-
# document[name].each do |value|
|
47
|
-
# puts " * #{value} (#{value.type})"
|
48
|
-
# end
|
49
|
-
# end
|
50
|
-
#
|
51
|
-
# @see https://cloud.google.com/search/documents_indexes Documents and
|
52
|
-
# fields
|
53
|
-
#
|
54
|
-
class Fields
|
55
|
-
include Enumerable
|
56
|
-
|
57
|
-
##
|
58
|
-
# @private Create a new empty fields object.
|
59
|
-
def initialize
|
60
|
-
@hash = {}
|
61
|
-
end
|
62
|
-
|
63
|
-
##
|
64
|
-
# Retrieve the field values associated to a field name.
|
65
|
-
#
|
66
|
-
# @param [String] name The name of the field. New values will be
|
67
|
-
# configured with this name.
|
68
|
-
#
|
69
|
-
# @return [FieldValues]
|
70
|
-
#
|
71
|
-
# @example
|
72
|
-
# require "gcloud"
|
73
|
-
#
|
74
|
-
# gcloud = Gcloud.new
|
75
|
-
# search = gcloud.search
|
76
|
-
# index = search.index "products"
|
77
|
-
#
|
78
|
-
# document = index.document "product-sku-000001"
|
79
|
-
# puts "The document description is:"
|
80
|
-
# document.fields["description"].each do |value|
|
81
|
-
# puts "* #{value} (#{value.type}) [#{value.lang}]"
|
82
|
-
# end
|
83
|
-
#
|
84
|
-
def [] name
|
85
|
-
@hash[name] ||= FieldValues.new name
|
86
|
-
end
|
87
|
-
|
88
|
-
##
|
89
|
-
# Add a new value. If the field name does not exist it will be added. If
|
90
|
-
# the field value is a DateTime or Numeric, or the type is set to
|
91
|
-
# `:datetime` or `:number`, then the added value will replace any existing
|
92
|
-
# values of the same type (since there can be only one).
|
93
|
-
#
|
94
|
-
# @param [String] name The name of the field.
|
95
|
-
# @param [String, Datetime, Float] value The value to add to the field.
|
96
|
-
# @param [Symbol] type The type of the field value. An attempt is made to
|
97
|
-
# set the correct type when this option is missing, although it must be
|
98
|
-
# provided for `:geo` values. A field can have multiple values with same
|
99
|
-
# or different types; however, it cannot have multiple `:datetime` or
|
100
|
-
# `:number` values.
|
101
|
-
#
|
102
|
-
# The following values are supported:
|
103
|
-
#
|
104
|
-
# * `:default` - The value is a string. The format will be automatically
|
105
|
-
# detected. This is the default value for strings.
|
106
|
-
# * `:text` - The value is a string with maximum length 1024**2
|
107
|
-
# characters.
|
108
|
-
# * `:html` - The value is an HTML-formatted string with maximum length
|
109
|
-
# 1024**2 characters.
|
110
|
-
# * `:atom` - The value is a string with maximum length 500 characters.
|
111
|
-
# * `:geo` - The value is a point on earth described by latitude and
|
112
|
-
# longitude coordinates, represented in string with any of the listed
|
113
|
-
# [ways of writing coordinates](http://en.wikipedia.org/wiki/Geographic_coordinate_conversion).
|
114
|
-
# * `:datetime` - The value is a `DateTime`.
|
115
|
-
# * `:number` - The value is a `Numeric` between -2,147,483,647 and
|
116
|
-
# 2,147,483,647. The value will be stored as a double precision
|
117
|
-
# floating point value in Cloud Search.
|
118
|
-
# @param [String] lang The language of a string value. Must be a valid
|
119
|
-
# [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes).
|
120
|
-
#
|
121
|
-
# @example
|
122
|
-
# require "gcloud"
|
123
|
-
#
|
124
|
-
# gcloud = Gcloud.new
|
125
|
-
# search = gcloud.search
|
126
|
-
# index = search.index "products"
|
127
|
-
#
|
128
|
-
# document = index.document "product-sku-000001"
|
129
|
-
# document.fields.add "sku", "product-sku-000001", type: :atom
|
130
|
-
# document.fields.add "description", "The best T-shirt ever.",
|
131
|
-
# type: :text, lang: "en"
|
132
|
-
# document.fields.add "description", "<p>The best T-shirt ever.</p>",
|
133
|
-
# type: :html, lang: "en"
|
134
|
-
# document.fields.add "price", 24.95
|
135
|
-
#
|
136
|
-
def add name, value, type: nil, lang: nil
|
137
|
-
@hash[name] ||= FieldValues.new name
|
138
|
-
@hash[name].add value, type: type, lang: lang
|
139
|
-
end
|
140
|
-
|
141
|
-
##
|
142
|
-
# Deletes a field and all values.
|
143
|
-
#
|
144
|
-
# @param [String] name The name of the field.
|
145
|
-
#
|
146
|
-
# @example
|
147
|
-
# require "gcloud"
|
148
|
-
#
|
149
|
-
# gcloud = Gcloud.new
|
150
|
-
# search = gcloud.search
|
151
|
-
# index = search.index "products"
|
152
|
-
#
|
153
|
-
# document = index.document "product-sku-000001"
|
154
|
-
# document.fields.delete "description"
|
155
|
-
#
|
156
|
-
def delete name, &block
|
157
|
-
@hash.delete name, &block
|
158
|
-
end
|
159
|
-
|
160
|
-
##
|
161
|
-
# Calls block once for each field, passing the field name and values pair
|
162
|
-
# as parameters. If no block is given an enumerator is returned instead.
|
163
|
-
#
|
164
|
-
# @example
|
165
|
-
# require "gcloud"
|
166
|
-
#
|
167
|
-
# gcloud = Gcloud.new
|
168
|
-
# search = gcloud.search
|
169
|
-
# index = search.index "products"
|
170
|
-
#
|
171
|
-
# document = index.document "product-sku-000001"
|
172
|
-
# puts "The document #{document.doc_id} has the following fields:"
|
173
|
-
# document.fields.each do |name, values|
|
174
|
-
# puts "* #{name}:"
|
175
|
-
# values.each do |value|
|
176
|
-
# puts " * #{value} (#{value.type})"
|
177
|
-
# end
|
178
|
-
# end
|
179
|
-
#
|
180
|
-
def each &block
|
181
|
-
# Only yield fields that have values.
|
182
|
-
fields_with_values.each(&block)
|
183
|
-
end
|
184
|
-
|
185
|
-
##
|
186
|
-
# Returns a new array populated with all the field names.
|
187
|
-
#
|
188
|
-
# @example
|
189
|
-
# require "gcloud"
|
190
|
-
#
|
191
|
-
# gcloud = Gcloud.new
|
192
|
-
# search = gcloud.search
|
193
|
-
# index = search.index "products"
|
194
|
-
#
|
195
|
-
# document = index.document "product-sku-000001"
|
196
|
-
# puts "The document #{document.doc_id} has the following fields:"
|
197
|
-
# document.fields.names.each do |name|
|
198
|
-
# puts "* #{name}:"
|
199
|
-
# end
|
200
|
-
#
|
201
|
-
def names
|
202
|
-
# Only return fields that have values.
|
203
|
-
fields_with_values.keys
|
204
|
-
end
|
205
|
-
|
206
|
-
##
|
207
|
-
# @private Create a new Fields instance from a raw Hash.
|
208
|
-
def self.from_raw raw
|
209
|
-
hsh = {}
|
210
|
-
raw.each do |k, v|
|
211
|
-
hsh[k] = FieldValues.from_raw k, v["values"]
|
212
|
-
end unless raw.nil?
|
213
|
-
fields = new
|
214
|
-
fields.instance_variable_set "@hash", hsh
|
215
|
-
fields
|
216
|
-
end
|
217
|
-
|
218
|
-
##
|
219
|
-
# @private Create a raw Hash object containing all the field names and
|
220
|
-
# values.
|
221
|
-
def to_raw
|
222
|
-
hsh = {}
|
223
|
-
@hash.each do |k, v|
|
224
|
-
hsh[k] = v.to_raw unless v.empty?
|
225
|
-
end
|
226
|
-
hsh
|
227
|
-
end
|
228
|
-
|
229
|
-
protected
|
230
|
-
|
231
|
-
##
|
232
|
-
# @private Find all the fields that have values. This is needed because a
|
233
|
-
# field is required to have at least one value.
|
234
|
-
#
|
235
|
-
# Users can remove all values, and the empty FieldValues object will
|
236
|
-
# remain in the internal hash. This is the same as not having that field.
|
237
|
-
#
|
238
|
-
# Users can also reference the field by name before adding a value. So we
|
239
|
-
# have multiple valid use cases which add an empty FieldValues object to
|
240
|
-
# the hash.
|
241
|
-
def fields_with_values
|
242
|
-
@hash.select { |_name, values| values.any? }
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|
data/lib/gcloud/search/index.rb
DELETED
@@ -1,572 +0,0 @@
|
|
1
|
-
# Copyright 2015 Google Inc. All rights reserved.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
|
15
|
-
|
16
|
-
require "gcloud/search/document"
|
17
|
-
require "gcloud/search/index/list"
|
18
|
-
require "gcloud/search/result"
|
19
|
-
|
20
|
-
module Gcloud
|
21
|
-
module Search
|
22
|
-
##
|
23
|
-
# # Index
|
24
|
-
#
|
25
|
-
# An index manages {Document} instances for retrieval. Indexes cannot be
|
26
|
-
# created, updated, or deleted directly on the server: They are derived from
|
27
|
-
# the documents that reference them. You can manage groups of documents by
|
28
|
-
# putting them into separate indexes.
|
29
|
-
#
|
30
|
-
# With an index, you can retrieve documents with
|
31
|
-
# {Gcloud::Search::Index#find} and {Gcloud::Search::Index#documents}; manage
|
32
|
-
# them with {Gcloud::Search::Index#document}, {Gcloud::Search::Index#save},
|
33
|
-
# and {Gcloud::Search::Index#remove}; and perform searches over their fields
|
34
|
-
# with {Gcloud::Search::Index#search}.
|
35
|
-
#
|
36
|
-
# @example
|
37
|
-
# require "gcloud"
|
38
|
-
#
|
39
|
-
# gcloud = Gcloud.new
|
40
|
-
# search = gcloud.search
|
41
|
-
# index = search.index "books"
|
42
|
-
#
|
43
|
-
# results = index.search "dark stormy"
|
44
|
-
# results.each do |result|
|
45
|
-
# puts result.doc_id
|
46
|
-
# end
|
47
|
-
#
|
48
|
-
# @see https://cloud.google.com/search/documents_indexes Documents and
|
49
|
-
# Indexes
|
50
|
-
#
|
51
|
-
class Index
|
52
|
-
##
|
53
|
-
# @private The Connection object.
|
54
|
-
attr_accessor :connection
|
55
|
-
|
56
|
-
##
|
57
|
-
# @private The raw data object.
|
58
|
-
attr_accessor :raw
|
59
|
-
|
60
|
-
##
|
61
|
-
# @private Creates a new Index instance.
|
62
|
-
#
|
63
|
-
def initialize
|
64
|
-
@connection = nil
|
65
|
-
@raw = nil
|
66
|
-
end
|
67
|
-
|
68
|
-
##
|
69
|
-
# The index identifier. May be defined by the server or by the client.
|
70
|
-
# Must be unique within the project. It cannot be an empty string. It must
|
71
|
-
# contain only visible, printable ASCII characters (ASCII codes 33 through
|
72
|
-
# 126 inclusive) and be no longer than 100 characters. It cannot begin
|
73
|
-
# with an exclamation point (<code>!</code>), and it cannot begin and end
|
74
|
-
# with double underscores (<code>__</code>).
|
75
|
-
def index_id
|
76
|
-
@raw["indexId"]
|
77
|
-
end
|
78
|
-
|
79
|
-
##
|
80
|
-
# The names of fields in which TEXT values are stored.
|
81
|
-
# @see https://cloud.google.com/search/documents_indexes#index_schemas
|
82
|
-
# Index schemas
|
83
|
-
def text_fields
|
84
|
-
return @raw["indexedField"]["textFields"] if @raw["indexedField"]
|
85
|
-
[]
|
86
|
-
end
|
87
|
-
|
88
|
-
##
|
89
|
-
# The names of fields in which HTML values are stored.
|
90
|
-
# @see https://cloud.google.com/search/documents_indexes#index_schemas
|
91
|
-
# Index schemas
|
92
|
-
def html_fields
|
93
|
-
return @raw["indexedField"]["htmlFields"] if @raw["indexedField"]
|
94
|
-
[]
|
95
|
-
end
|
96
|
-
|
97
|
-
##
|
98
|
-
# The names of fields in which ATOM values are stored.
|
99
|
-
# @see https://cloud.google.com/search/documents_indexes#index_schemas
|
100
|
-
# Index schemas
|
101
|
-
def atom_fields
|
102
|
-
return @raw["indexedField"]["atomFields"] if @raw["indexedField"]
|
103
|
-
[]
|
104
|
-
end
|
105
|
-
|
106
|
-
##
|
107
|
-
# The names of fields in which DATE values are stored.
|
108
|
-
# @see https://cloud.google.com/search/documents_indexes#index_schemas
|
109
|
-
# Index schemas
|
110
|
-
def datetime_fields
|
111
|
-
return @raw["indexedField"]["dateFields"] if @raw["indexedField"]
|
112
|
-
[]
|
113
|
-
end
|
114
|
-
|
115
|
-
##
|
116
|
-
# The names of fields in which NUMBER values are stored.
|
117
|
-
# @see https://cloud.google.com/search/documents_indexes#index_schemas
|
118
|
-
# Index schemas
|
119
|
-
def number_fields
|
120
|
-
return @raw["indexedField"]["numberFields"] if @raw["indexedField"]
|
121
|
-
[]
|
122
|
-
end
|
123
|
-
|
124
|
-
##
|
125
|
-
# The names of fields in which GEO values are stored.
|
126
|
-
# @see https://cloud.google.com/search/documents_indexes#index_schemas
|
127
|
-
# Index schemas
|
128
|
-
def geo_fields
|
129
|
-
return @raw["indexedField"]["geoFields"] if @raw["indexedField"]
|
130
|
-
[]
|
131
|
-
end
|
132
|
-
|
133
|
-
##
|
134
|
-
# The names of all the fields that are stored on the index.
|
135
|
-
def field_names
|
136
|
-
(text_fields + html_fields + atom_fields + datetime_fields +
|
137
|
-
number_fields + geo_fields).uniq
|
138
|
-
end
|
139
|
-
|
140
|
-
##
|
141
|
-
# The field value types that are stored on the field name.
|
142
|
-
def field_types_for name
|
143
|
-
{
|
144
|
-
text: text_fields.include?(name),
|
145
|
-
html: html_fields.include?(name),
|
146
|
-
atom: atom_fields.include?(name),
|
147
|
-
datetime: datetime_fields.include?(name),
|
148
|
-
number: number_fields.include?(name),
|
149
|
-
geo: geo_fields.include?(name)
|
150
|
-
}.delete_if { |_k, v| !v }.keys
|
151
|
-
end
|
152
|
-
|
153
|
-
##
|
154
|
-
# Retrieves an existing document by id.
|
155
|
-
#
|
156
|
-
# @param [String, Gcloud::Search::Document] doc_id The id of a document or
|
157
|
-
# a Document instance.
|
158
|
-
# @return [Gcloud::Search::Document, nil] Returns `nil` if the document
|
159
|
-
# does not exist
|
160
|
-
#
|
161
|
-
# @example
|
162
|
-
# require "gcloud"
|
163
|
-
#
|
164
|
-
# gcloud = Gcloud.new
|
165
|
-
# search = gcloud.search
|
166
|
-
# index = search.index "products"
|
167
|
-
#
|
168
|
-
# document = index.find "product-sku-000001"
|
169
|
-
# puts document.doc_id
|
170
|
-
#
|
171
|
-
def find doc_id
|
172
|
-
# Get the id if passes a Document object
|
173
|
-
doc_id = doc_id.doc_id if doc_id.respond_to? :doc_id
|
174
|
-
ensure_connection!
|
175
|
-
resp = connection.get_doc index_id, doc_id
|
176
|
-
return Document.from_hash(JSON.parse(resp.body)) if resp.success?
|
177
|
-
return nil if resp.status == 404
|
178
|
-
fail ApiError.from_response(resp)
|
179
|
-
rescue JSON::ParserError
|
180
|
-
raise ApiError.from_response(resp)
|
181
|
-
end
|
182
|
-
alias_method :get, :find
|
183
|
-
|
184
|
-
##
|
185
|
-
# Helper for creating a new Document instance. The returned instance is
|
186
|
-
# local: It is either not yet saved to the service (see
|
187
|
-
# {Gcloud::Search::Index#save}), or if it has been given the id of an
|
188
|
-
# existing document, it is not yet populated with the document's data (see
|
189
|
-
# {Gcloud::Search::Index#find}).
|
190
|
-
#
|
191
|
-
# @param [String, nil] doc_id An optional unique ID for the new document.
|
192
|
-
# When the document is saved, this value must contain only visible,
|
193
|
-
# printable ASCII characters (ASCII codes 33 through 126 inclusive) and
|
194
|
-
# be no longer than 500 characters. It cannot begin with an exclamation
|
195
|
-
# point (<code>!</code>), and it cannot begin and end with double
|
196
|
-
# underscores (<code>__</code>).
|
197
|
-
# @param [Integer, nil] rank An optional rank for the new document. An
|
198
|
-
# integer which determines the default ordering of documents returned
|
199
|
-
# from a search. It is a bad idea to assign the same rank to many
|
200
|
-
# documents, and the same rank should never be assigned to more than
|
201
|
-
# 10,000 documents. By default (when it is not specified or set to 0),
|
202
|
-
# it is set at the time the document is saved to the number of seconds
|
203
|
-
# since January 1, 2011. The rank can be used in the `expressions`,
|
204
|
-
# `order`, and `fields` options in {Gcloud::Search::Index#search}, where
|
205
|
-
# it should referenced as `rank`.
|
206
|
-
#
|
207
|
-
# @return [Gcloud::Search::Document]
|
208
|
-
#
|
209
|
-
# @example
|
210
|
-
# require "gcloud"
|
211
|
-
#
|
212
|
-
# gcloud = Gcloud.new
|
213
|
-
# search = gcloud.search
|
214
|
-
# index = search.index "products"
|
215
|
-
#
|
216
|
-
# document = index.document "product-sku-000001"
|
217
|
-
# document.doc_id #=> nil
|
218
|
-
# document.rank #=> nil
|
219
|
-
#
|
220
|
-
# @example To check if an index already contains a document:
|
221
|
-
# require "gcloud"
|
222
|
-
#
|
223
|
-
# gcloud = Gcloud.new
|
224
|
-
# search = gcloud.search
|
225
|
-
# index = search.index "products"
|
226
|
-
#
|
227
|
-
# document = index.document "product-sku-000001"
|
228
|
-
# document = index.find document # returns nil if not present
|
229
|
-
#
|
230
|
-
def document doc_id = nil, rank = nil
|
231
|
-
Document.new.tap do |d|
|
232
|
-
d.doc_id = doc_id
|
233
|
-
d.rank = rank
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
##
|
238
|
-
# Retrieves the list of documents belonging to the index.
|
239
|
-
#
|
240
|
-
# @param [String] token A previously-returned page token representing part
|
241
|
-
# of the larger set of results to view.
|
242
|
-
# @param [Integer] max Maximum number of documents to return. The default
|
243
|
-
# is `100`.
|
244
|
-
# @return [Array<Gcloud::Search::Document>] See
|
245
|
-
# {Gcloud::Search::Document::List})
|
246
|
-
#
|
247
|
-
# @example
|
248
|
-
# require "gcloud"
|
249
|
-
#
|
250
|
-
# gcloud = Gcloud.new
|
251
|
-
# search = gcloud.search
|
252
|
-
# index = search.index "products"
|
253
|
-
#
|
254
|
-
# documents = index.documents
|
255
|
-
# documents.each do |index|
|
256
|
-
# puts index.index_id
|
257
|
-
# end
|
258
|
-
#
|
259
|
-
# @example With pagination: (See {Gcloud::Search::Document::List})
|
260
|
-
# require "gcloud"
|
261
|
-
#
|
262
|
-
# gcloud = Gcloud.new
|
263
|
-
# search = gcloud.search
|
264
|
-
# index = search.index "products"
|
265
|
-
#
|
266
|
-
# documents = index.documents
|
267
|
-
# loop do
|
268
|
-
# documents.each do |index|
|
269
|
-
# puts index.index_id
|
270
|
-
# end
|
271
|
-
# break unless documents.next?
|
272
|
-
# documents = documents.next
|
273
|
-
# end
|
274
|
-
#
|
275
|
-
def documents token: nil, max: nil, view: nil
|
276
|
-
ensure_connection!
|
277
|
-
options = { token: token, max: max, view: view }
|
278
|
-
resp = connection.list_docs index_id, options
|
279
|
-
return Document::List.from_response(resp, self) if resp.success?
|
280
|
-
fail ApiError.from_response(resp)
|
281
|
-
end
|
282
|
-
|
283
|
-
##
|
284
|
-
# Saves a new or existing document to the index. If the document instance
|
285
|
-
# is new and has been given an id (see {Gcloud::Search::Index#document}),
|
286
|
-
# it will replace an existing document in the index that has the same
|
287
|
-
# unique id.
|
288
|
-
#
|
289
|
-
# @param [Gcloud::Search::Document] document A Document instance, either
|
290
|
-
# new (see {Gcloud::Search::Index#document}) or existing (see
|
291
|
-
# {Gcloud::Search::Index#find}).
|
292
|
-
#
|
293
|
-
# @return [Gcloud::Search::Document]
|
294
|
-
#
|
295
|
-
# @example
|
296
|
-
# require "gcloud"
|
297
|
-
#
|
298
|
-
# gcloud = Gcloud.new
|
299
|
-
# search = gcloud.search
|
300
|
-
# index = search.index "products"
|
301
|
-
#
|
302
|
-
# document = index.document "product-sku-000001"
|
303
|
-
# document.doc_id #=> nil
|
304
|
-
# document.rank #=> nil
|
305
|
-
#
|
306
|
-
# document = index.save document
|
307
|
-
# document.doc_id #=> "-2486020449015432113"
|
308
|
-
# document.rank #=> 154223228
|
309
|
-
#
|
310
|
-
def save document
|
311
|
-
ensure_connection!
|
312
|
-
resp = connection.create_doc index_id, document.to_hash
|
313
|
-
if resp.success?
|
314
|
-
raw = document.instance_variable_get "@raw"
|
315
|
-
raw.merge! JSON.parse(resp.body)
|
316
|
-
return document
|
317
|
-
end
|
318
|
-
fail ApiError.from_response(resp)
|
319
|
-
rescue JSON::ParserError
|
320
|
-
raise ApiError.from_response(resp)
|
321
|
-
end
|
322
|
-
|
323
|
-
##
|
324
|
-
# Permanently deletes the document from the index.
|
325
|
-
#
|
326
|
-
# @param [String] doc_id The id of the document.
|
327
|
-
# @return [Boolean] `true` if successful
|
328
|
-
#
|
329
|
-
# @example
|
330
|
-
# require "gcloud"
|
331
|
-
#
|
332
|
-
# gcloud = Gcloud.new
|
333
|
-
# search = gcloud.search
|
334
|
-
# index = search.index "products"
|
335
|
-
#
|
336
|
-
# index.remove "product-sku-000001"
|
337
|
-
#
|
338
|
-
def remove doc_id
|
339
|
-
# Get the id if passes a Document object
|
340
|
-
doc_id = doc_id.doc_id if doc_id.respond_to? :doc_id
|
341
|
-
ensure_connection!
|
342
|
-
resp = connection.delete_doc index_id, doc_id
|
343
|
-
return true if resp.success?
|
344
|
-
fail ApiError.from_response(resp)
|
345
|
-
end
|
346
|
-
|
347
|
-
##
|
348
|
-
# Permanently deletes the index by deleting its documents. (Indexes cannot
|
349
|
-
# be created, updated, or deleted directly on the server: They are derived
|
350
|
-
# from the documents that reference them.)
|
351
|
-
#
|
352
|
-
# @param [Boolean] force If `true`, ensures the deletion of the index by
|
353
|
-
# first deleting all documents. If `false` and the index contains
|
354
|
-
# documents, the request will fail. Default is `false`.
|
355
|
-
#
|
356
|
-
# @example
|
357
|
-
# require "gcloud"
|
358
|
-
#
|
359
|
-
# gcloud = Gcloud.new
|
360
|
-
# search = gcloud.search
|
361
|
-
# index = search.index "books"
|
362
|
-
# index.delete
|
363
|
-
#
|
364
|
-
# @example Deleting an index containing documents with the `force` option:
|
365
|
-
# require "gcloud"
|
366
|
-
#
|
367
|
-
# gcloud = Gcloud.new
|
368
|
-
# search = gcloud.search
|
369
|
-
# index = search.index "books"
|
370
|
-
# index.delete force: true
|
371
|
-
#
|
372
|
-
def delete force: false
|
373
|
-
ensure_connection!
|
374
|
-
docs_to_be_removed = documents view: "ID_ONLY"
|
375
|
-
return if docs_to_be_removed.empty?
|
376
|
-
unless force
|
377
|
-
fail "Unable to delete because documents exist. Use force option."
|
378
|
-
end
|
379
|
-
while docs_to_be_removed
|
380
|
-
docs_to_be_removed.each { |d| remove d }
|
381
|
-
if docs_to_be_removed.next?
|
382
|
-
docs_to_be_removed = documents token: docs_to_be_removed.token,
|
383
|
-
view: "ID_ONLY"
|
384
|
-
else
|
385
|
-
docs_to_be_removed = nil
|
386
|
-
end
|
387
|
-
end
|
388
|
-
end
|
389
|
-
|
390
|
-
##
|
391
|
-
# @private New Index from a raw data object.
|
392
|
-
def self.from_raw raw, conn
|
393
|
-
new.tap do |f|
|
394
|
-
f.raw = raw
|
395
|
-
f.connection = conn
|
396
|
-
end
|
397
|
-
end
|
398
|
-
|
399
|
-
# rubocop:disable Metrics/LineLength
|
400
|
-
# Disabled because there are links in the docs that are long.
|
401
|
-
|
402
|
-
##
|
403
|
-
# Runs a search against the documents in the index using the provided
|
404
|
-
# query.
|
405
|
-
#
|
406
|
-
# By default, Result objects are sorted by document rank. For more information
|
407
|
-
# see the [REST API documentation for Document.rank](https://cloud.google.com/search/reference/rest/v1/projects/indexes/documents#resource_representation.google.cloudsearch.v1.Document.rank).
|
408
|
-
#
|
409
|
-
# You can specify how to sort results with the `order` option. In the
|
410
|
-
# example below, the <code>-</code> character before `avg_review` means
|
411
|
-
# that results will be sorted in ascending order by `published` and then
|
412
|
-
# in descending order by `avg_review`. You can add computed fields with
|
413
|
-
# the `expressions` option, and limit the fields that are returned with
|
414
|
-
# the `fields` option.
|
415
|
-
#
|
416
|
-
# @see https://cloud.google.com/search/reference/rest/v1/projects/indexes/search
|
417
|
-
# The REST API documentation for indexes.search
|
418
|
-
#
|
419
|
-
# @param [String] query The query string in search query syntax. If the
|
420
|
-
# query is `nil` or empty, all documents are returned. For more
|
421
|
-
# information see [Query
|
422
|
-
# Strings](https://cloud.google.com/search/query).
|
423
|
-
# @param [Hash] expressions Customized expressions used in `order` or
|
424
|
-
# `fields`. The expression can contain fields in Document, the built-in
|
425
|
-
# fields ( `rank`, the document `rank`, and `score` if scoring is
|
426
|
-
# enabled) and fields defined in `expressions`. All field expressions
|
427
|
-
# expressed as a `Hash` with the keys as the `name` and the values as
|
428
|
-
# the `expression`. The expression value can be a combination of
|
429
|
-
# supported functions encoded in the string. Expressions involving
|
430
|
-
# number fields can use the arithmetical operators (+, -, *, /) and the
|
431
|
-
# built-in numeric functions (`max`, `min`, `pow`, `count`, `log`,
|
432
|
-
# `abs`). Expressions involving geopoint fields can use the `geopoint`
|
433
|
-
# and `distance` functions. Expressions for text and html fields can use
|
434
|
-
# the `snippet` function.
|
435
|
-
# @param [Integer] matched_count_accuracy Minimum accuracy requirement for
|
436
|
-
# {Result::List#matched_count}. If specified, `matched_count` will be
|
437
|
-
# accurate to at least that number. For example, when set to 100, any
|
438
|
-
# <code>matched_count <= 100</code> is accurate. This option may add
|
439
|
-
# considerable latency/expense. By default (when it is not specified or
|
440
|
-
# set to 0), the accuracy is the same as `max`.
|
441
|
-
# @param [Integer] offset Used to advance pagination to an arbitrary
|
442
|
-
# result, independent of the previous results. Offsets are an
|
443
|
-
# inefficient alternative to using `token`. (Both cannot be both set.)
|
444
|
-
# The default is 0.
|
445
|
-
# @param [String] order A comma-separated list of fields for sorting on
|
446
|
-
# the search result, including fields from Document, the built-in fields
|
447
|
-
# (`rank` and `score`), and fields defined in expressions. The default
|
448
|
-
# sorting order is ascending. To specify descending order for a field, a
|
449
|
-
# suffix <code>" desc"</code> should be appended to the field name. For
|
450
|
-
# example: <code>orderBy="foo desc,bar"</code>. The default value for
|
451
|
-
# text sort is the empty string, and the default value for numeric sort
|
452
|
-
# is 0. If not specified, the search results are automatically sorted by
|
453
|
-
# descending `rank`. Sorting by ascending `rank` is not allowed.
|
454
|
-
# @param [String, Array<String>] fields The fields to return in the
|
455
|
-
# {Search::Result} objects. These can be fields from {Document}, the
|
456
|
-
# built-in fields `rank` and `score`, and fields defined in expressions.
|
457
|
-
# The default is to return all fields.
|
458
|
-
# @param [String, Symbol] scorer The scoring function to invoke on a
|
459
|
-
# search result for this query. If scorer is not set, scoring is
|
460
|
-
# disabled and `score` is 0 for all documents in the search result. To
|
461
|
-
# enable document relevancy score based on term frequency, set `scorer`
|
462
|
-
# to `:generic`.
|
463
|
-
# @param [Integer] scorer_size Maximum number of top retrieved results to
|
464
|
-
# score. It is valid only when `scorer` is set. The default is 100.
|
465
|
-
# @param [String] token A previously-returned page token representing part
|
466
|
-
# of the larger set
|
467
|
-
# of results to view.
|
468
|
-
# @param [Integer] max Maximum number of results to return per page.
|
469
|
-
#
|
470
|
-
# @return [Array<Gcloud::Search::Result>] (See
|
471
|
-
# {Gcloud::Search::Result::List})
|
472
|
-
#
|
473
|
-
# @example
|
474
|
-
# require "gcloud"
|
475
|
-
#
|
476
|
-
# gcloud = Gcloud.new
|
477
|
-
# search = gcloud.search
|
478
|
-
# index = search.index "books"
|
479
|
-
#
|
480
|
-
# results = index.search "dark stormy"
|
481
|
-
# results.each do |result|
|
482
|
-
# puts result.doc_id
|
483
|
-
# end
|
484
|
-
#
|
485
|
-
# @example With pagination: (See {Gcloud::Search::Result::List})
|
486
|
-
# require "gcloud"
|
487
|
-
#
|
488
|
-
# gcloud = Gcloud.new
|
489
|
-
# search = gcloud.search
|
490
|
-
# index = search.index "books"
|
491
|
-
#
|
492
|
-
# results = index.results
|
493
|
-
# loop do
|
494
|
-
# results.each do |result|
|
495
|
-
# puts result.doc_id
|
496
|
-
# end
|
497
|
-
# break unless results.next?
|
498
|
-
# results = results.next
|
499
|
-
# end
|
500
|
-
#
|
501
|
-
# @example With the `order` option:
|
502
|
-
# require "gcloud"
|
503
|
-
#
|
504
|
-
# gcloud = Gcloud.new
|
505
|
-
# search = gcloud.search
|
506
|
-
# index = search.index "books"
|
507
|
-
#
|
508
|
-
# results = index.search "dark stormy", order: "published, avg_review desc"
|
509
|
-
# documents = index.search query # API call
|
510
|
-
#
|
511
|
-
# @example With the `fields` option:
|
512
|
-
# require "gcloud"
|
513
|
-
#
|
514
|
-
# gcloud = Gcloud.new
|
515
|
-
# search = gcloud.search
|
516
|
-
# index = search.index "products"
|
517
|
-
#
|
518
|
-
# results = index.search "cotton T-shirt",
|
519
|
-
# expressions: { total_price: "(price + tax)" },
|
520
|
-
# fields: ["name", "total_price", "highlight"]
|
521
|
-
#
|
522
|
-
# @example Just as in documents, data is accessible via {Fields} methods:
|
523
|
-
# require "gcloud"
|
524
|
-
#
|
525
|
-
# gcloud = Gcloud.new
|
526
|
-
# search = gcloud.search
|
527
|
-
# index = search.index "products"
|
528
|
-
# document = index.find "product-sku-000001"
|
529
|
-
# results = index.search "cotton T-shirt"
|
530
|
-
# values = results[0]["description"]
|
531
|
-
#
|
532
|
-
# values[0] #=> "100% organic cotton ruby gem T-shirt"
|
533
|
-
# values[0].type #=> :text
|
534
|
-
# values[0].lang #=> "en"
|
535
|
-
# values[1] #=> "<p>100% organic cotton ruby gem T-shirt</p>"
|
536
|
-
# values[1].type #=> :html
|
537
|
-
# values[1].lang #=> "en"
|
538
|
-
#
|
539
|
-
def search query, expressions: nil, matched_count_accuracy: nil,
|
540
|
-
offset: nil, order: nil, fields: nil, scorer: nil,
|
541
|
-
scorer_size: nil, token: nil, max: nil
|
542
|
-
ensure_connection!
|
543
|
-
options = { expressions: format_expressions(expressions),
|
544
|
-
matched_count_accuracy: matched_count_accuracy,
|
545
|
-
offset: offset, order: order, fields: fields,
|
546
|
-
scorer: scorer, scorer_size: scorer_size, token: token,
|
547
|
-
max: max }
|
548
|
-
resp = connection.search index_id, query, options
|
549
|
-
if resp.success?
|
550
|
-
Result::List.from_response resp, self, query, options
|
551
|
-
else
|
552
|
-
fail ApiError.from_response(resp)
|
553
|
-
end
|
554
|
-
end
|
555
|
-
|
556
|
-
# rubocop:enable Metrics/LineLength
|
557
|
-
|
558
|
-
protected
|
559
|
-
|
560
|
-
##
|
561
|
-
# Raise an error unless an active connection is available.
|
562
|
-
def ensure_connection!
|
563
|
-
fail "Must have active connection" unless connection
|
564
|
-
end
|
565
|
-
|
566
|
-
def format_expressions expressions
|
567
|
-
return nil if expressions.nil?
|
568
|
-
expressions.to_h.map { |k, v| { name: k, expression: v } }
|
569
|
-
end
|
570
|
-
end
|
571
|
-
end
|
572
|
-
end
|