Commit 53dbcfec7432e5829091d37a2ed080d6e670711c

Authored by Andrew Kane
1 parent 0895c2fd

Support select

README.md
... ... @@ -88,7 +88,7 @@ Searchkick supports the complete [Elasticsearch Search API](https://www.elastic.
88 88 Query like SQL
89 89  
90 90 ```ruby
91   -Product.search "apples", where: {in_stock: true}, limit: 10, offset: 50
  91 +Product.search("apples").where(in_stock: true).limit(10).offset(50)
92 92 ```
93 93  
94 94 Search specific fields
... ... @@ -100,7 +100,7 @@ fields: [:name, :brand]
100 100 Where
101 101  
102 102 ```ruby
103   -where: {
  103 +where(
104 104 expires_at: {gt: Time.now}, # lt, gte, lte also available
105 105 orders_count: 1..10, # equivalent to {gte: 1, lte: 10}
106 106 aisle_id: [25, 30], # in
... ... @@ -114,13 +114,13 @@ where: {
114 114 _or: [{in_stock: true}, {backordered: true}],
115 115 _and: [{in_stock: true}, {backordered: true}],
116 116 _not: {store_id: 1} # negate a condition
117   -}
  117 +)
118 118 ```
119 119  
120 120 Order
121 121  
122 122 ```ruby
123   -order: {_score: :desc} # most relevant first - default
  123 +order(_score: :desc) # most relevant first - default
124 124 ```
125 125  
126 126 [All of these sort options are supported](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html)
... ... @@ -128,13 +128,13 @@ order: {_score: :desc} # most relevant first - default
128 128 Limit / offset
129 129  
130 130 ```ruby
131   -limit: 20, offset: 40
  131 +limit(20).offset(40)
132 132 ```
133 133  
134 134 Select
135 135  
136 136 ```ruby
137   -select: [:name]
  137 +select([:name])
138 138 ```
139 139  
140 140 [These source filtering options are supported](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#request-body-search-source-filtering)
... ...
lib/searchkick/relation.rb
... ... @@ -66,6 +66,22 @@ module Searchkick
66 66 self
67 67 end
68 68  
  69 + def select(*fields, &block)
  70 + if block_given?
  71 + # TODO better error message
  72 + raise ArgumentError, "too many arguments" if fields.any?
  73 + records.select(&block)
  74 + else
  75 + spawn.select!(*fields)
  76 + end
  77 + end
  78 +
  79 + # TODO decide how to handle block form
  80 + def select!(*fields)
  81 + options[:select] = Array(options[:select]) + fields
  82 + self
  83 + end
  84 +
69 85 # same as Active Record
70 86 def inspect
71 87 entries = results.first(11).map!(&:inspect)
... ...
test/sql_test.rb
... ... @@ -92,7 +92,9 @@ class SqlTest < Minitest::Test
92 92 def test_select
93 93 store [{name: "Product A", store_id: 1}]
94 94 result = Product.search("product", load: false, select: [:name, :store_id]).first
95   - assert_equal %w(id name store_id), result.keys.reject { |k| k.start_with?("_") }.sort
  95 + expected = %w(id name store_id)
  96 + assert_equal expected, result.keys.reject { |k| k.start_with?("_") }.sort
  97 + assert_equal expected, Product.search("product", relation: true, load: false).select(:name, :store_id).first.keys.reject { |k| k.start_with?("_") }.sort
96 98 assert_equal "Product A", result.name
97 99 assert_equal 1, result.store_id
98 100 end
... ...