我写了一个小厨师库,看起来像这样:
module Test
module Search
extend self
def single_node(type, value)
result = Chef::Search::Query.new.search(:node, "#{type}:#{value}",
filter_result: {
'name' => ['name']
}).map { |n| n['name'] }.first
return result
end
end
end
当针对它运行测试代码时,我收到以下错误:
TypeError
---------
no implicit conversion of String into Integer
1: module Test
2: module Search
3: extend self
4: def single_node(type, value)
5: result = Chef::Search::Query.new.search(:node, "#{type}:#{value}",
6: filter_result: {
7: 'name' => ['name']
8>> }).map { |n| n['name'] }.first
9: return result
10: end
13: end
14:
经过一番游戏,我发现搜索包含了这些信息:
[[{"name"=>"influxdb.example.org"}], 0, 1].
这看起来很奇怪,因为在Chef DSL中搜索时使用的搜索选项会返回不同的内容。
答案 0 :(得分:2)
在您正在调用the search method in recipe DSL的食谱中执行搜索时,该食谱已经在结果发送之前迭代结果。
当您调用Chef::Sarch::Query.new.search
时,您正在调用dsl帮助程序中的underlying method并且如果您未将块传递给方法来处理结果,则必须自己迭代结果
你最终here返回一个包含查询结果数组的数组,以及结果的开始和大小(用于UI上的分页)。
所以@Oleander已经给出了最终答案,在first
之前调用map
,在返回的结果部分(第一个数组条目)中调用map
忽略分页变量
或者为了获得与食谱DSL相同的行为,使用像这样的Chef :: DSL :: DataQuery:
require 'chef/dsl/data_query'
module Test
module Search
extend self
include Chef::DSL::DataQuery
def single_node(type, value)
result = search(:node, "#{type}:#{value}",
filter_result: {
'name' => ['name']
}).map { |n| n['name'] }.first
return result
end
end
end
关于缩短代码的相同想法:
require 'chef/dsl/data_query'
module Test
module Search
extend self
include Chef::DSL::DataQuery
def single_node(type, value)
return search(:node, "#{type}:#{value}",
filter_result: {
'name' => ['name']
}).first['name']
end
end
end
返回第一个结果并得到它的名称,应该更快一些,因为它不必“子集”所有条目,只有第一个。
答案 1 :(得分:1)
如果您发布的内容是您的返回值,那么只需在其上运行first
即可。
result = Chef::Search::Query.new.search(:node, "#{type}:#{value}", filter_result: {
'name' => ['name']
}).first.map { |n| n['name'] }.first