Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support filter result in search options #75

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion libraries/search/overrides.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ module Overrides
# This search() method returns a block iterator or an Array, depending
# on how this method is called.
def search(obj, query=nil, sort=nil, start=0, rows=1000, &block)
if !sort.nil?
if !sort.nil? and sort.keys != [:filter_result]
raise "Sorting search results is not supported"
end
_query = Query.parse(query)
Expand All @@ -54,6 +54,9 @@ def search(obj, query=nil, sort=nil, start=0, rows=1000, &block)
_result += bags
end

if sort.respond_to?(:has_key?) and sort.has_key?(:filter_result)
_result.map! { |r| apply_filter_result(r, sort[:filter_result]) }
end

if block_given?
pos = 0
Expand All @@ -66,6 +69,23 @@ def search(obj, query=nil, sort=nil, start=0, rows=1000, &block)
end
end

def apply_filter_result(result, filter)
filtered = {}
filter.each_pair do |k, path|
filtered[k.to_s] = hash_path(result, path)
end
filtered
end

def hash_path(value, path)
path.each do |k|
value = value[k]
end
value
rescue
nil
end

def search_nodes(_query, start, rows, &block)
_result = []
node_path = Chef::Config[:nodes_path] || File.join(Chef::Config[:data_bag_path], "node")
Expand Down
57 changes: 36 additions & 21 deletions tests/test_search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
require File.expand_path('../../libraries/search', __FILE__)

module SearchDbTests

def test_search_all
# try to get data of all users
nodes = search(:users, "*:*")
Expand All @@ -40,33 +40,33 @@ def test_search_all
nodes = search(:users, nil)
assert_equal nodes.length, 4
end

def test_search_exact_match
nodes = search(:users, "username:speedy")
assert_equal nodes.length, 1
assert_equal nodes[0]["username"], "speedy"
end

def test_get_all_with_field
nodes = search(:users, "username:*")
assert nodes.length > 0
assert nodes.all?{|x| !x["username"].nil?}
end

def test_get_all_without_field
nodes = search(:users, "(NOT username:*)")
assert nodes.length == 0
nodes = search(:users, "(NOT color:*)")
assert nodes.length == 3
assert nodes.all?{|x| x["color"].nil?}
end

def test_get_all_but_speedy
nodes = search(:users, "NOT username:speedy")
assert nodes.length > 0
assert nodes.all?{|x| x["username"] != "speedy"}
end

def test_array_includes
nodes = search(:users, "children:tom")
assert nodes.length == 2
Expand All @@ -75,7 +75,7 @@ def test_array_includes
assert nodes.length == 1
assert nodes.all?{ |x| x["children"].include?("jerry") }
end

def test_boolean
nodes = search(:users, "married:true")
assert nodes.length == 3
Expand All @@ -84,24 +84,24 @@ def test_boolean
assert nodes.length == 1
assert nodes[0]["married"] == false
end

def test_integer
nodes = search(:users, "age:35")
assert nodes.length == 1
assert nodes[0]["age"] == 35
end

def test_AND_condition
nodes = search(:users, "married:true AND age:35")
assert nodes.length == 1
assert nodes[0]["username"] == "lea"
end

def test_OR_condition
nodes = search(:users, "age:42 OR age:22")
assert nodes.length == 2
end

def test_NOT_condition
nodes = search(:users, "children:tom AND (NOT gender:female)")
assert nodes.length == 1
Expand All @@ -110,37 +110,37 @@ def test_NOT_condition
nodes = search(:users, "children:tom AND (NOT gender:female) AND (NOT age:42)")
assert nodes.length == 0
end

def test_any_value
nodes = search(:users, "children:*")
assert nodes.length == 2
end

def test_any_value_lucene_range
nodes = search(:users, "address:[* TO *]")
assert nodes.length == 2
end

def test_general_lucene_range_fails
assert_raises RuntimeError do
nodes = search(:users, "children:[aaa TO zzz]")
end
end

def test_block_usage
# bracket syntax
result = []
search(:users, "*:*") {|x| result << x["id"]}
assert result.length == 4

# do...end syntax
result = []
search(:users) do |x|
result << x["id"]
end
assert result.length == 4
end

def test_check_escaped_chars
nodes = search(:users, 'tag:tag\:\:test')
assert nodes.length == 1
Expand All @@ -155,7 +155,7 @@ def test_check_escaped_chars
nodes = search(:users, "tags:tag\\:\\:*")
assert nodes.length == 1
end

def test_wildcards
nodes = search(:users, "gender:f??ale")
assert nodes.length == 1
Expand All @@ -164,7 +164,7 @@ def test_wildcards
nodes = search(:users, "username:spee*")
assert nodes.length == 1
end

def test_empty_field_value
assert_raise(RuntimeError) {
search(:users, "gender:#{nil} AND age:35")
Expand All @@ -176,18 +176,26 @@ def test_empty_field_value
search(:users, "gender:\"\" AND age:35")
}
end

def test_OR_group
nodes = search(:users, "id:(mike OR tom)")
assert nodes.length == 2
end

def test_nested_fieldnames
nodes = search(:users, "address_street:wilhelmsstrasse")
assert nodes.length == 1
nodes = search(:users, "address_street_floor:1")
assert nodes.length == 1
end

def test_search_with_filter_result
nodes = search(:users, "id:(mike OR tom)", :filter_result => {
:addr => ['address', 'street', 'floor']
})
assert_equal 1, nodes[0]['addr']
assert_equal nil, nodes[1]['addr']
end
end

module SearchNodeTests
Expand Down Expand Up @@ -218,6 +226,13 @@ def test_search_node_without_json_class
nodes = search(:node, "chef_environment:default")
assert_equal 3, nodes.length
end

def test_search_with_filter_result
nodes = search(:node, "chef_environment:default", :filter_result => {
:hostname => ['hostname']
})
assert_equal [['hostname'], ['hostname'], ['hostname']], nodes.map(&:keys)
end
end

module ImplicitSearchDB
Expand Down