couchbase 3.0.0.beta.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +227 -0
  3. data/.rubocop_todo.yml +47 -0
  4. data/CONTRIBUTING.md +110 -0
  5. data/Gemfile +4 -0
  6. data/README.md +3 -3
  7. data/Rakefile +1 -1
  8. data/couchbase.gemspec +40 -39
  9. data/examples/analytics.rb +123 -108
  10. data/examples/auth.rb +33 -0
  11. data/examples/crud.rb +16 -2
  12. data/examples/managing_analytics_indexes.rb +18 -4
  13. data/examples/managing_buckets.rb +17 -3
  14. data/examples/managing_collections.rb +22 -9
  15. data/examples/managing_query_indexes.rb +38 -18
  16. data/examples/managing_search_indexes.rb +21 -6
  17. data/examples/managing_view_indexes.rb +18 -4
  18. data/examples/query.rb +17 -3
  19. data/examples/query_with_consistency.rb +30 -20
  20. data/examples/search.rb +116 -101
  21. data/examples/search_with_consistency.rb +43 -30
  22. data/examples/subdocument.rb +42 -30
  23. data/examples/view.rb +19 -10
  24. data/ext/CMakeLists.txt +40 -2
  25. data/ext/build_version.hxx.in +1 -1
  26. data/ext/couchbase/bucket.hxx +190 -38
  27. data/ext/couchbase/cluster.hxx +22 -4
  28. data/ext/couchbase/configuration.hxx +14 -14
  29. data/ext/couchbase/couchbase.cxx +108 -12
  30. data/ext/couchbase/error_map.hxx +202 -2
  31. data/ext/couchbase/errors.hxx +8 -2
  32. data/ext/couchbase/io/dns_client.hxx +6 -6
  33. data/ext/couchbase/io/http_command.hxx +2 -2
  34. data/ext/couchbase/io/http_session.hxx +7 -11
  35. data/ext/couchbase/io/http_session_manager.hxx +3 -3
  36. data/ext/couchbase/io/mcbp_command.hxx +101 -44
  37. data/ext/couchbase/io/mcbp_session.hxx +144 -49
  38. data/ext/couchbase/io/retry_action.hxx +30 -0
  39. data/ext/couchbase/io/retry_context.hxx +39 -0
  40. data/ext/couchbase/io/retry_orchestrator.hxx +96 -0
  41. data/ext/couchbase/io/retry_reason.hxx +235 -0
  42. data/ext/couchbase/io/retry_strategy.hxx +156 -0
  43. data/ext/couchbase/operations/document_decrement.hxx +2 -0
  44. data/ext/couchbase/operations/document_exists.hxx +2 -0
  45. data/ext/couchbase/operations/document_get.hxx +2 -0
  46. data/ext/couchbase/operations/document_get_and_lock.hxx +2 -0
  47. data/ext/couchbase/operations/document_get_and_touch.hxx +2 -0
  48. data/ext/couchbase/operations/document_get_projected.hxx +2 -0
  49. data/ext/couchbase/operations/document_increment.hxx +2 -0
  50. data/ext/couchbase/operations/document_insert.hxx +2 -0
  51. data/ext/couchbase/operations/document_lookup_in.hxx +2 -0
  52. data/ext/couchbase/operations/document_mutate_in.hxx +3 -0
  53. data/ext/couchbase/operations/document_query.hxx +10 -0
  54. data/ext/couchbase/operations/document_remove.hxx +2 -0
  55. data/ext/couchbase/operations/document_replace.hxx +2 -0
  56. data/ext/couchbase/operations/document_search.hxx +8 -3
  57. data/ext/couchbase/operations/document_touch.hxx +2 -0
  58. data/ext/couchbase/operations/document_unlock.hxx +2 -0
  59. data/ext/couchbase/operations/document_upsert.hxx +2 -0
  60. data/ext/couchbase/operations/query_index_create.hxx +14 -4
  61. data/ext/couchbase/operations/query_index_drop.hxx +12 -2
  62. data/ext/couchbase/operations/query_index_get_all.hxx +11 -2
  63. data/ext/couchbase/origin.hxx +47 -17
  64. data/ext/couchbase/platform/backtrace.c +189 -0
  65. data/ext/couchbase/platform/backtrace.h +54 -0
  66. data/ext/couchbase/platform/terminate_handler.cc +122 -0
  67. data/ext/couchbase/platform/terminate_handler.h +36 -0
  68. data/ext/couchbase/protocol/cmd_get_cluster_config.hxx +6 -1
  69. data/ext/couchbase/protocol/status.hxx +14 -4
  70. data/ext/couchbase/version.hxx +2 -2
  71. data/ext/extconf.rb +39 -36
  72. data/ext/test/main.cxx +64 -16
  73. data/lib/couchbase.rb +0 -1
  74. data/lib/couchbase/analytics_options.rb +2 -4
  75. data/lib/couchbase/authenticator.rb +14 -0
  76. data/lib/couchbase/binary_collection.rb +9 -9
  77. data/lib/couchbase/binary_collection_options.rb +8 -6
  78. data/lib/couchbase/bucket.rb +18 -18
  79. data/lib/couchbase/cluster.rb +121 -90
  80. data/lib/couchbase/collection.rb +36 -38
  81. data/lib/couchbase/collection_options.rb +31 -17
  82. data/lib/couchbase/common_options.rb +1 -1
  83. data/lib/couchbase/datastructures/couchbase_list.rb +16 -16
  84. data/lib/couchbase/datastructures/couchbase_map.rb +18 -18
  85. data/lib/couchbase/datastructures/couchbase_queue.rb +13 -13
  86. data/lib/couchbase/datastructures/couchbase_set.rb +8 -7
  87. data/lib/couchbase/errors.rb +10 -3
  88. data/lib/couchbase/json_transcoder.rb +2 -2
  89. data/lib/couchbase/management/analytics_index_manager.rb +37 -37
  90. data/lib/couchbase/management/bucket_manager.rb +25 -25
  91. data/lib/couchbase/management/collection_manager.rb +3 -3
  92. data/lib/couchbase/management/query_index_manager.rb +59 -14
  93. data/lib/couchbase/management/search_index_manager.rb +15 -12
  94. data/lib/couchbase/management/user_manager.rb +1 -1
  95. data/lib/couchbase/management/view_index_manager.rb +11 -5
  96. data/lib/couchbase/mutation_state.rb +12 -0
  97. data/lib/couchbase/query_options.rb +23 -9
  98. data/lib/couchbase/scope.rb +61 -1
  99. data/lib/couchbase/search_options.rb +40 -27
  100. data/lib/couchbase/subdoc.rb +31 -28
  101. data/lib/couchbase/version.rb +2 -2
  102. data/lib/couchbase/view_options.rb +0 -1
  103. metadata +22 -9
@@ -1,25 +1,33 @@
1
- require 'couchbase'
2
- include Couchbase
1
+ # Copyright 2020 Couchbase, Inc.
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
+ require "couchbase"
16
+ include Couchbase # rubocop:disable Style/MixinUsage for brevity
3
17
 
4
18
  def measure(msg)
5
19
  start = Time.now
6
20
  yield
7
- printf "%s in %.2f seconds\n", msg, Time.now - start
21
+ printf "%<msg>s in %<elapsed>.2f seconds\n", msg: msg, elapsed: Time.now - start
8
22
  end
9
23
 
10
24
  def display_indexes(indexes, bucket_name)
11
25
  puts "There are #{indexes.size} query indexes in the bucket \"#{bucket_name}\":"
12
26
  indexes.each do |index|
13
27
  print " * [#{index.state}] #{index.name}"
14
- if index.primary?
15
- print " (primary)"
16
- end
17
- unless index.index_key.empty?
18
- print " on [#{index.index_key.join(", ")}]"
19
- end
20
- if index.condition
21
- print " where #{index.condition}"
22
- end
28
+ print " (primary)" if index.primary?
29
+ print " on [#{index.index_key.join(', ')}]" unless index.index_key.empty?
30
+ print " where #{index.condition}" if index.condition
23
31
  puts
24
32
  end
25
33
  end
@@ -35,29 +43,41 @@ display_indexes(cluster.query_indexes.get_all_indexes(bucket_name), bucket_name)
35
43
  index_name = "demo_index"
36
44
  options = Management::QueryIndexManager::DropIndexOptions.new
37
45
  options.ignore_if_does_not_exist = true
38
- measure("Index \"#{index_name}\" has been dropped") { cluster.query_indexes.drop_index(bucket_name, index_name, options) }
46
+ measure("Index \"#{index_name}\" has been dropped") do
47
+ cluster.query_indexes.drop_index(bucket_name, index_name, options)
48
+ end
39
49
 
40
50
  options = Management::QueryIndexManager::CreateIndexOptions.new
41
51
  options.ignore_if_exists = true
42
52
  options.condition = "abv > 2"
43
- measure("Index \"#{index_name}\" has been created") { cluster.query_indexes.create_index(bucket_name, index_name, %w[`type` `name`], options) }
53
+ measure("Index \"#{index_name}\" has been created") do
54
+ cluster.query_indexes.create_index(bucket_name, index_name, %w[`type` `name`], options)
55
+ end
44
56
 
45
57
  options = Management::QueryIndexManager::DropPrimaryIndexOptions.new
46
58
  options.ignore_if_does_not_exist = true
47
- measure("Primary index \"#{bucket_name}\" has been dropped") { cluster.query_indexes.drop_primary_index(bucket_name, options) }
59
+ measure("Primary index \"#{bucket_name}\" has been dropped") do
60
+ cluster.query_indexes.drop_primary_index(bucket_name, options)
61
+ end
48
62
 
49
63
  options = Management::QueryIndexManager::CreatePrimaryIndexOptions.new
50
64
  options.deferred = true
51
- measure("Primary index \"#{bucket_name}\" has been created") { cluster.query_indexes.create_primary_index(bucket_name, options) }
65
+ measure("Primary index \"#{bucket_name}\" has been created") do
66
+ cluster.query_indexes.create_primary_index(bucket_name, options)
67
+ end
52
68
 
53
69
  display_indexes(cluster.query_indexes.get_all_indexes(bucket_name), bucket_name)
54
70
 
55
- measure("Build of the indexes for \"#{bucket_name}\" has been triggered") { cluster.query_indexes.build_deferred_indexes(bucket_name) }
71
+ measure("Build of the indexes for \"#{bucket_name}\" has been triggered") do
72
+ cluster.query_indexes.build_deferred_indexes(bucket_name)
73
+ end
56
74
 
57
75
  display_indexes(cluster.query_indexes.get_all_indexes(bucket_name), bucket_name)
58
76
 
59
77
  options = Management::QueryIndexManager::WatchIndexesOptions.new
60
78
  options.watch_primary = true
61
- measure("Watching for primary index build completion for \"#{bucket_name}\" has been finished") { cluster.query_indexes.watch_indexes(bucket_name, [], 10_000_000, options) }
79
+ measure("Watching for primary index build completion for \"#{bucket_name}\" has been finished") do
80
+ cluster.query_indexes.watch_indexes(bucket_name, [], 10_000_000, options)
81
+ end
62
82
 
63
83
  display_indexes(cluster.query_indexes.get_all_indexes(bucket_name), bucket_name)
@@ -1,10 +1,24 @@
1
+ # Copyright 2020 Couchbase, Inc.
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
+
1
15
  require "couchbase"
2
- include Couchbase
16
+ include Couchbase # rubocop:disable Style/MixinUsage for brevity
3
17
 
4
18
  def measure(msg)
5
19
  start = Time.now
6
20
  yield
7
- printf "%s in %.2f seconds\n", msg, Time.now - start
21
+ printf "%<msg>s in %<elapsed>.2f seconds\n", msg: msg, elapsed: Time.now - start
8
22
  end
9
23
 
10
24
  options = Cluster::ClusterOptions.new
@@ -42,20 +56,21 @@ loop do
42
56
  sleep(1)
43
57
  num = cluster.search_indexes.get_indexed_documents_count(search_index_name)
44
58
  break if num_indexed == num
59
+
45
60
  num_indexed = num
46
61
  puts "#{index.name.inspect} indexed #{num_indexed}"
47
62
  end
48
63
 
49
64
  search_indexes = cluster.search_indexes.get_all_indexes
50
65
  puts "There are #{search_indexes.size} search indexes on the cluster"
51
- search_indexes.each do |index|
52
- num_docs = cluster.search_indexes.get_indexed_documents_count(index.name)
66
+ search_indexes.each do |idx|
67
+ num_docs = cluster.search_indexes.get_indexed_documents_count(idx.name)
53
68
  puts "* #{index.name.inspect} contains #{num_docs} documents"
54
69
  end
55
70
 
56
71
  document = {
57
- title: "Hello world",
58
- content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
72
+ title: "Hello world",
73
+ content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
59
74
  }
60
75
  analysis = cluster.search_indexes.analyze_document(search_index_name, document)
61
76
  puts "Analysis of document using definition of the index #{search_index_name}:"
@@ -1,10 +1,24 @@
1
+ # Copyright 2020 Couchbase, Inc.
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
+
1
15
  require "couchbase"
2
- include Couchbase
16
+ include Couchbase # rubocop:disable Style/MixinUsage for brevity
3
17
 
4
18
  def measure(msg)
5
19
  start = Time.now
6
20
  yield
7
- printf "%s in %.2f seconds\n", msg, Time.now - start
21
+ printf "%<msg>s in %<elapsed>.2f seconds\n", msg: msg, elapsed: Time.now - start
8
22
  end
9
23
 
10
24
  def display_indexes(manager, namespace)
@@ -14,8 +28,8 @@ def display_indexes(manager, namespace)
14
28
  puts " * #{index.name} (#{index.views.size} views)"
15
29
  index.views.each do |name, view|
16
30
  puts " - #{name}"
17
- puts " map:\n#{view.map.strip.gsub(/^/, " | ")}" if view.has_map?
18
- puts " reduce:\n#{view.reduce.strip.gsub(/^/, " | ")}" if view.has_reduce?
31
+ puts " map:\n#{view.map.strip.gsub(/^/, ' | ')}" if view.has_map?
32
+ puts " reduce:\n#{view.reduce.strip.gsub(/^/, ' | ')}" if view.has_reduce?
19
33
  end
20
34
  end
21
35
  end
@@ -1,6 +1,20 @@
1
- require 'couchbase'
1
+ # Copyright 2020 Couchbase, Inc.
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.
2
14
 
3
- include Couchbase
15
+ require "couchbase"
16
+
17
+ include Couchbase # rubocop:disable Style/MixinUsage for brevity
4
18
 
5
19
  options = Cluster::ClusterOptions.new
6
20
  options.authenticate("Administrator", "password")
@@ -13,6 +27,6 @@ options.named_parameters({type: "hotel"})
13
27
  options.metrics = true
14
28
  res = cluster.query("SELECT * FROM `travel-sample` WHERE type = $type LIMIT 10", options)
15
29
  res.rows.each do |row|
16
- puts "#{row["travel-sample"]["country"]}. #{row["travel-sample"]["name"]}"
30
+ puts "#{row['travel-sample']['country']}. #{row['travel-sample']['name']}"
17
31
  end
18
32
  puts "Status: #{res.meta_data.status}. Execution time: #{res.meta_data.metrics.execution_time}"
@@ -1,6 +1,20 @@
1
- require 'couchbase'
1
+ # Copyright 2020 Couchbase, Inc.
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.
2
14
 
3
- include Couchbase
15
+ require "couchbase"
16
+
17
+ include Couchbase # rubocop:disable Style/MixinUsage for brevity
4
18
 
5
19
  options = Cluster::ClusterOptions.new
6
20
  options.authenticate("Administrator", "password")
@@ -21,9 +35,9 @@ puts "METHOD 1: using :request_plus"
21
35
 
22
36
  random_number = rand(0..1_000_000_000)
23
37
  collection.upsert("user:#{random_number}", {
24
- "name" => ["Brass", "Doorknob"],
25
- "email" => "brass.doorknob@example.com",
26
- "data" => random_number,
38
+ "name" => %w[Brass Doorknob],
39
+ "email" => "brass.doorknob@example.com",
40
+ "data" => random_number,
27
41
  })
28
42
 
29
43
  options = Cluster::QueryOptions.new
@@ -32,12 +46,10 @@ options.positional_parameters(["Brass"])
32
46
  options.scan_consistency = :request_plus
33
47
  res = cluster.query("SELECT name, email, data, META(`default`).id FROM `default` WHERE $1 IN name", options)
34
48
  res.rows.each do |row|
35
- puts "Name: #{row["name"].join(" ")}, e-mail: #{row["email"]}, data: #{row["data"]}"
36
- if row["data"] == random_number
37
- puts "--- Found our newly created document!"
38
- end
39
- if ENV['REMOVE_DOOR_KNOBS']
40
- puts "Removing #{row["id"]} (requested via env)"
49
+ puts "Name: #{row['name'].join(' ')}, e-mail: #{row['email']}, data: #{row['data']}"
50
+ puts "--- Found our newly created document!" if row["data"] == random_number
51
+ if ENV["REMOVE_DOOR_KNOBS"]
52
+ puts "Removing #{row['id']} (requested via env)"
41
53
  collection.remove(row["id"])
42
54
  end
43
55
  end
@@ -51,9 +63,9 @@ puts "METHOD 2: using MutationState"
51
63
 
52
64
  random_number = rand(0..1_000_000_000)
53
65
  res = collection.upsert("user:#{random_number}", {
54
- "name" => ["Brass", "Doorknob"],
55
- "email" => "brass.doorknob@example.com",
56
- "data" => random_number,
66
+ "name" => %w[Brass Doorknob],
67
+ "email" => "brass.doorknob@example.com",
68
+ "data" => random_number,
57
69
  })
58
70
 
59
71
  state = MutationState.new(res.mutation_token)
@@ -65,12 +77,10 @@ options.positional_parameters(["Brass"])
65
77
  options.consistent_with(state)
66
78
  res = cluster.query("SELECT name, email, data, META(`default`).id FROM `default` WHERE $1 IN name", options)
67
79
  res.rows.each do |row|
68
- puts "Name: #{row["name"].join(" ")}, e-mail: #{row["email"]}, data: #{row["data"]}"
69
- if row["data"] == random_number
70
- puts "--- Found our newly created document!"
71
- end
72
- if ENV['REMOVE_DOOR_KNOBS']
73
- puts "Removing #{row["id"]} (requested via env)"
80
+ puts "Name: #{row['name'].join(' ')}, e-mail: #{row['email']}, data: #{row['data']}"
81
+ puts "--- Found our newly created document!" if row["data"] == random_number
82
+ if ENV["REMOVE_DOOR_KNOBS"]
83
+ puts "Removing #{row['id']} (requested via env)"
74
84
  collection.remove(row["id"])
75
85
  end
76
86
  end
@@ -1,6 +1,20 @@
1
- require 'couchbase'
2
-
3
- include Couchbase
1
+ # Copyright 2020 Couchbase, Inc.
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
+ require "couchbase"
16
+
17
+ include Couchbase # rubocop:disable Style/MixinUsage for brevity
4
18
 
5
19
  options = Cluster::ClusterOptions.new
6
20
  options.authenticate("Administrator", "password")
@@ -18,91 +32,91 @@ rescue Error::IndexNotFound
18
32
  index.source_type = "couchbase"
19
33
  index.source_name = "beer-sample"
20
34
  index.params = {
21
- mapping: {
22
- default_datetime_parser: "dateTimeOptional",
23
- types: {
24
- "beer" => {
25
- properties: {
26
- "abv" => {
27
- fields: [
28
- {
29
- name: "abv",
30
- type: "number",
31
- include_in_all: true,
32
- index: true,
33
- store: true,
34
- docvalues: true,
35
- }
36
- ]
37
- },
38
- "category" => {
39
- fields: [
40
- {
41
- name: "category",
42
- type: "text",
43
- include_in_all: true,
44
- include_term_vectors: true,
45
- index: true,
46
- store: true,
47
- docvalues: true,
48
- }
49
- ]
50
- },
51
- "description" => {
52
- fields: [
53
- {
54
- name: "description",
55
- type: "text",
56
- include_in_all: true,
57
- include_term_vectors: true,
58
- index: true,
59
- store: true,
60
- docvalues: true,
61
- }
62
- ]
63
- },
64
- "name" => {
65
- fields: [
66
- {
67
- name: "name",
68
- type: "text",
69
- include_in_all: true,
70
- include_term_vectors: true,
71
- index: true,
72
- store: true,
73
- docvalues: true,
74
- }
75
- ]
76
- },
77
- "style" => {
78
- fields: [
79
- {
80
- name: "style",
81
- type: "text",
82
- include_in_all: true,
83
- include_term_vectors: true,
84
- index: true,
85
- store: true,
86
- docvalues: true,
87
- }
88
- ]
89
- },
90
- "updated" => {
91
- fields: [
92
- {
93
- name: "updated",
94
- type: "datetime",
95
- include_in_all: true,
96
- index: true,
97
- store: true,
98
- docvalues: true,
99
- }
100
- ]
101
- },
102
- }
103
- }
104
- }
105
- }
35
+ mapping: {
36
+ default_datetime_parser: "dateTimeOptional",
37
+ types: {
38
+ "beer" => {
39
+ properties: {
40
+ "abv" => {
41
+ fields: [
42
+ {
43
+ name: "abv",
44
+ type: "number",
45
+ include_in_all: true,
46
+ index: true,
47
+ store: true,
48
+ docvalues: true,
49
+ },
50
+ ],
51
+ },
52
+ "category" => {
53
+ fields: [
54
+ {
55
+ name: "category",
56
+ type: "text",
57
+ include_in_all: true,
58
+ include_term_vectors: true,
59
+ index: true,
60
+ store: true,
61
+ docvalues: true,
62
+ },
63
+ ],
64
+ },
65
+ "description" => {
66
+ fields: [
67
+ {
68
+ name: "description",
69
+ type: "text",
70
+ include_in_all: true,
71
+ include_term_vectors: true,
72
+ index: true,
73
+ store: true,
74
+ docvalues: true,
75
+ },
76
+ ],
77
+ },
78
+ "name" => {
79
+ fields: [
80
+ {
81
+ name: "name",
82
+ type: "text",
83
+ include_in_all: true,
84
+ include_term_vectors: true,
85
+ index: true,
86
+ store: true,
87
+ docvalues: true,
88
+ },
89
+ ],
90
+ },
91
+ "style" => {
92
+ fields: [
93
+ {
94
+ name: "style",
95
+ type: "text",
96
+ include_in_all: true,
97
+ include_term_vectors: true,
98
+ index: true,
99
+ store: true,
100
+ docvalues: true,
101
+ },
102
+ ],
103
+ },
104
+ "updated" => {
105
+ fields: [
106
+ {
107
+ name: "updated",
108
+ type: "datetime",
109
+ include_in_all: true,
110
+ index: true,
111
+ store: true,
112
+ docvalues: true,
113
+ },
114
+ ],
115
+ },
116
+ },
117
+ },
118
+ },
119
+ },
106
120
  }
107
121
 
108
122
  cluster.search_indexes.upsert_index(index)
@@ -112,6 +126,7 @@ rescue Error::IndexNotFound
112
126
  sleep(1)
113
127
  num = cluster.search_indexes.get_indexed_documents_count(search_index_name)
114
128
  break if num_indexed == num
129
+
115
130
  num_indexed = num
116
131
  puts "indexing #{search_index_name.inspect}: #{num_indexed} documents"
117
132
  end
@@ -125,24 +140,24 @@ options.fields = %w[name]
125
140
  options.highlight_style = :html
126
141
  options.highlight_fields = %w[name description]
127
142
  options.sort = [
128
- Cluster::SearchSort.field("abv") do |spec|
129
- spec.type = :number
130
- end,
131
- Cluster::SearchSort.score do |spec|
132
- spec.desc = true
133
- end,
134
- "category",
135
- Cluster::SearchSort.id,
143
+ Cluster::SearchSort.field("abv") do |spec|
144
+ spec.type = :number
145
+ end,
146
+ Cluster::SearchSort.score do |spec|
147
+ spec.desc = true
148
+ end,
149
+ "category",
150
+ Cluster::SearchSort.id,
136
151
  ]
137
152
 
138
153
  res = cluster.search_query(search_index_name, query, options)
139
154
  res.rows.each_with_index do |row, idx|
140
155
  document = row.fields
141
- puts "\n#{idx}. #{document["name"]} (id: #{row.id.inspect})"
156
+ puts "\n#{idx}. #{document['name']} (id: #{row.id.inspect})"
142
157
  row.fragments.each do |field, fragments|
143
158
  puts " * #{field}"
144
159
  fragments.each do |fragment|
145
- puts " - #{fragment.gsub(/\n/, ' ')}"
160
+ puts " - #{fragment.tr("\n", ' ')}"
146
161
  end
147
162
  end
148
163
  end
@@ -171,17 +186,17 @@ options.facets["by_strength"] = numeric_facet
171
186
 
172
187
  res = cluster.search_query(search_index_name, query, options)
173
188
 
174
- puts "\n==== Top 3 beer names (out of #{res.facets["by_name"].total}):"
189
+ puts "\n==== Top 3 beer names (out of #{res.facets['by_name'].total}):"
175
190
  res.facets["by_name"].terms.each_with_index do |term, idx|
176
191
  puts "#{idx}. #{term.term} (#{term.count} records)"
177
192
  end
178
193
 
179
- puts "\n==== Beer by strength (out of #{res.facets["by_strength"].total}):"
194
+ puts "\n==== Beer by strength (out of #{res.facets['by_strength'].total}):"
180
195
  res.facets["by_strength"].numeric_ranges.each_with_index do |range, idx|
181
196
  puts "#{idx}. #{range.name}, ABV: [#{range.min}..#{range.max}] (#{range.count} records)"
182
197
  end
183
198
 
184
- puts "\n==== The most recently updated (out of #{res.facets["by_time"].total}):"
199
+ puts "\n==== The most recently updated (out of #{res.facets['by_time'].total}):"
185
200
  res.facets["by_time"].date_ranges.each_with_index do |range, idx|
186
201
  puts "#{idx}. #{range.name} [#{range.start_time}..#{range.end_time}] (#{range.count} records)"
187
202
  end