使用单独的哈希构建动态查询
Building a dynamic query with separate hashes
好的,我整个早上都在想办法解决这个问题。假设您有一个如下所示的哈希:
{"luxury_shopper"=>"10", "movie_goer"=>"80"}
并且您想构建如下所示的查询:
Observation.search("something", boost_by: {biz_trv:{factor: 10}} && {day_com:{factor:100}})
到目前为止,我的方法是将传入的哈希值转换为如下所示:
[{:luxury_shopper=>{:factor=>"10"}}, {:movie_goer=>{:factor=>"80"}}]
通过像这样迭代原始哈希:
params[:filter].map {|k,v| {k.to_sym => {factor:v}}}
我遇到的问题是,由于我要构建的查询是由未知数量的哈希组成的,我将 "boost_by",我不能只做 filters[0] && filters[1]
我在这里被难住了。有谁知道我如何动态地将散列插入到我的查询中并将运算符放在它们之间?
编辑:
查询如下所示:
Observation.search("someting", boost_by: `insert hash` `insert operator` `insert hash` etc...)
上述查询可以有任意数量的散列和运算符。因此,如果用户想要将 10 个字段传递给 boost_by,我需要能够接受所有 10 个这些哈希值以及它们之间的任何运算符,例如,我的查询可能类似于以下任一示例:
Observation.search("something", boost_by: {biz_trv:{factor: 10}})
Observation.search("something", boost_by: {biz_trv:{factor: 12}} && {day_com:{factor:50}} && {location:{factor:40}})
我不确定是否正确理解你的问题,但如果你需要在任意数量的元素之间应用 &&
,你可以简单地使用 Enumerable#all? 方法,例如
filters = [{biz_trv:{factor: 10}}, {day_com:{factor:100}}, …]
Observation.search("something", boost_by: filters.all?)
更新:
filters = [{biz_trv:{factor: 12}}, {day_com:{factor:50}},
{location:{factor:40}}]
Observation.search("something",
boost_by: filters.inject {|ac,e| ac && e})
假设您总是想使用相同的运算符,您希望将 map
的输出传递给行为类似于 inject
:
的东西
(params[:filter].map {|k,v| {k.to_sym => {factor:v}}}).inject() { |r,c| r && c }
注意:未测试!
我有一个解决方案,涉及形成查询字符串,然后使用 #send 方法将查询字符串传递给对象。
hash = {"luxury_shopper"=>"10", "movie_goer"=>"80"}
BLANK_PARAMS = "boost_by: "
params = BLANK_PARAMS
hash.each do |k, v|
if params == BLANK_PARAMS
params += "{#{k}: {factor: #{v}}}"
else
params += " && {#{k}: {factor: #{v}}}"
end
end
在此操作结束时,参数字符串将如下所示:
"boost_by: {luxury_shopper: {factor: 10}} && {movie_goer: { factor: 80}}"
因此,如果您现在想要 运行 以下命令:
Observation.search("something", boost_by: {luxury_shopper: {factor: 10}} && {movie_goer: {factor: 80}})
你可以这样使用#send:
Observation.send('search', 'something', params)
好的,我整个早上都在想办法解决这个问题。假设您有一个如下所示的哈希:
{"luxury_shopper"=>"10", "movie_goer"=>"80"}
并且您想构建如下所示的查询:
Observation.search("something", boost_by: {biz_trv:{factor: 10}} && {day_com:{factor:100}})
到目前为止,我的方法是将传入的哈希值转换为如下所示:
[{:luxury_shopper=>{:factor=>"10"}}, {:movie_goer=>{:factor=>"80"}}]
通过像这样迭代原始哈希:
params[:filter].map {|k,v| {k.to_sym => {factor:v}}}
我遇到的问题是,由于我要构建的查询是由未知数量的哈希组成的,我将 "boost_by",我不能只做 filters[0] && filters[1]
我在这里被难住了。有谁知道我如何动态地将散列插入到我的查询中并将运算符放在它们之间?
编辑:
查询如下所示:
Observation.search("someting", boost_by: `insert hash` `insert operator` `insert hash` etc...)
上述查询可以有任意数量的散列和运算符。因此,如果用户想要将 10 个字段传递给 boost_by,我需要能够接受所有 10 个这些哈希值以及它们之间的任何运算符,例如,我的查询可能类似于以下任一示例:
Observation.search("something", boost_by: {biz_trv:{factor: 10}})
Observation.search("something", boost_by: {biz_trv:{factor: 12}} && {day_com:{factor:50}} && {location:{factor:40}})
我不确定是否正确理解你的问题,但如果你需要在任意数量的元素之间应用 &&
,你可以简单地使用 Enumerable#all? 方法,例如
filters = [{biz_trv:{factor: 10}}, {day_com:{factor:100}}, …]
Observation.search("something", boost_by: filters.all?)
更新:
filters = [{biz_trv:{factor: 12}}, {day_com:{factor:50}},
{location:{factor:40}}]
Observation.search("something",
boost_by: filters.inject {|ac,e| ac && e})
假设您总是想使用相同的运算符,您希望将 map
的输出传递给行为类似于 inject
:
(params[:filter].map {|k,v| {k.to_sym => {factor:v}}}).inject() { |r,c| r && c }
注意:未测试!
我有一个解决方案,涉及形成查询字符串,然后使用 #send 方法将查询字符串传递给对象。
hash = {"luxury_shopper"=>"10", "movie_goer"=>"80"}
BLANK_PARAMS = "boost_by: "
params = BLANK_PARAMS
hash.each do |k, v|
if params == BLANK_PARAMS
params += "{#{k}: {factor: #{v}}}"
else
params += " && {#{k}: {factor: #{v}}}"
end
end
在此操作结束时,参数字符串将如下所示:
"boost_by: {luxury_shopper: {factor: 10}} && {movie_goer: { factor: 80}}"
因此,如果您现在想要 运行 以下命令:
Observation.search("something", boost_by: {luxury_shopper: {factor: 10}} && {movie_goer: {factor: 80}})
你可以这样使用#send:
Observation.send('search', 'something', params)