Elastic Search Multiple Fields - elasticsearch

I'm using Tire to index and search a database of cars:
create :mappings => {
:cars => {
:properties => {
:id => {:type => 'string', :index => 'not_analyzed', :include_in_all => true},
:user_id => {:type => 'string', :index => 'not_analyzed'},
:name => {:type => 'string', :analyzer => 'snowball' },
:time => {:type => 'long', :index => 'not_analyzed'},
:origin_country => {:type => 'string', :analyzer => 'keyword', :include_in_all => false},
:origin_state => {:type => 'string', :analyzer => 'keyword', :include_in_all => false},
:origin_city => {:type => 'string', :analyzer => 'keyword', :include_in_all => false},
:dealer_name => {:type => 'string', :analyzer => 'snowball', :boost => 1.5, :include_in_all => false}
}
}
}
And queries look like:
s = Tire.search Search.index_name do
query do |query|
query.text :_all, downcased_query, :type => :phrase
end
end
Right now if you search for "New York Joe Dealer" it will match if there is a dealer_name is "Joe Dealer" or if the origin_state is "New York" but not both. Is there a way to match origin_state is "New York" and "dealer_name" is "Joe Dealer" (or either)? The idea is I want a user to enter in a fre-form query string and be able to find the best matches possible and to a user they would expect to enter New York Joe Dealer and find all cars sold at Joe Dealer in New York (or all cars in New York or at Joe Dealer ranked lower).

The correct solution would be to use the multi_match query to perform the same query against multiple fields. It's supported in Tire, see https://github.com/karmi/tire/blob/master/test/integration/match_query_test.rb.
Tire.search Search.index_name do
query do |query|
query.match :dealer_name, downcased_query
query.match :origin_state, downcased_query
end
end
You can even use the phrase type if the query would contain both the dealer and state info in correct order, such as "New York Joe Dealer".

The solution was to move to a "match" type filter, and diable :type => :phrase, so:
query do |query|
query.match :_all, downcased_query
end
There are still some issues with sorting so that time is still a big input, but this resolves many of the issues.

Related

Fedex Ruby Gem: Customs Value is required - how to add?

I'm working with the Ruby gem 'FedEx', https://github.com/jazminschroeder/fedex.
I've set up my code for a development mode and I'm testing making a shipment.
However, I get stuck with the following error:
C:/Ruby22/lib/ruby/gems/2.2.0/gems/fedex-.10.1/lib/fedex/request/shipment.rb:134:in 'failure_response': Customs Value is required. (Fedex:: RateError) from C: /Ruby22/lib/ruby/gems/2.2.0/gems/fedex-.10.1/lib/fedex/request/shipment.rb:32:in 'process_request' from C: /Ruby22/lib/ruby/gems/2.2.0/gems/fedex-3.10.1/lib/fedex/shipment.rb:57:in 'ship' from C: /Ruby22/bin/css_fedex_v1.rb:92:in ''
It seems that I need to parse a 'Customs Value', probably as part of my 'packages' hash. However, I'm unable to find the relevant field for me to enter this in. Anyone who's experienced this and found a solution?
My code is as below:
require 'fedex'
fedex = Fedex::Shipment.new(:key => '***',
:password => '***',
:account_number => '***',
:meter => '***',
:mode => 'development')
shipper = { :name => "***",
:company => "***",
:phone_number => "***",
:address => "***",
:city => "***",
:postal_code => "***",
:country_code => "DK" }
recipient = { :name => "***",
:company => "***",
:phone_number => "***",
:address => "***",
:city => "***",
:postal_code => "***",
:country_code => "GB",
:residential => "false" }
packages = []
packages << {:weight => {:units => "LB", :value => 1}}
shipping_options = {:packaging_type => "YOUR_PACKAGING",
:drop_off_type => "REGULAR_PICKUP"}
rate = fedex.rate(:shipper=>shipper,
:recipient => recipient,
:packages => packages,
:shipping_options => shipping_options)
ship = fedex.ship(:shipper=>shipper,
:recipient => recipient,
:packages => packages,
:service_type => "INTERNATIONAL_PRIORITY",
:shipping_options => shipping_options)
puts ship[:completed_shipment_detail][:operational_detail][:transit_time]
Customs value is declared in their docs:
https://github.com/jazminschroeder/fedex/commit/9f1d4c67b829aaa4eeba9090c1a45d3bd507aab3#diff-4f122efb7c0d98120d8b7f0cd00998e4R106
customs_value = { :currency => "USD",
:amount => "200" }
As I understand you can pass it into the commodities hash or keep it separate.

Ruby/Highrise API - Not saving phone number?

So I've been using this same block of code for about 9 months and suddenly it has stopped saving a phone number into Highrise when a new Lead is generated... Any idea where things are going sideways? I never throws an error and happily saves the contact with everything except for the telephone number.
# create a contact Highrise from supplied information
#person = Highrise::Person.new(first_name: #lead.first_name.humanize,
last_name: #lead.last_name.humanize,
background: "automatically created by LSAL app",
contact_data: { email_addresses: [ { address: #lead.email, location: "Home" } ],
phones: [ { number: #lead.phone, location: "Mobile" } ] } )
#person.save # save contact
#person = Highrise::Person.create(:company_name => account.company, :first_name => account.first_name, :last_name => account.last_name, :contact_data => { :email_addresses => [{ :email_address => {:address => account.email, } }], :addresses => [{:address => {:city => account.city, :location =>"Work", :state => account.state, :country => account.country,:street => "#{account.address1} #{account.address2}" , :zip => account.zip} }], :phone_numbers => [{ :phone_number => { :number => number, :location =>"Work"}}] } )
Hope its helpful

How to make a Ruby application to send money to specific users?

I'm a Ruby user, who is trying to make a Ruby application that allows me to pay to my friends. My friends have Paypal account individually (i.e. sungpahfriend#hello.com ). I have a particular amount of money that I have to pay to my friends.
I have a business account. ( sungpah#hello.com ).
But I can't find how I can pay to my friend.
Do I have to put my credit card information or just my email address and amount of money? Also where should I put my friend's email address?
I really want to know how to this effectively. I'm looking forward to getting a feedback!
Best
require 'paypal-sdk-rest'
PayPal::SDK::Core::Config.load('config/paypal.yml', ENV['RACK_ENV'] || 'development')
PayPal::SDK.logger = Logger.new(STDERR)
PayPal::SDK.logger.level = Logger::INFO
PayPal::SDK.configure({
:mode => "sandbox",
:client_id => "xxx-xx",
:client_secret => "xx-xx"
})
#payment = PayPal::SDK::REST::Payment.new({
:intent => "sale",
:payer => {
:payment_method => "credit_card",
:funding_instruments => [{
:credit_card => {
:type => "visa",
:number => "4567516310777851",
:expire_month => "11",
:expire_year => "2018",
:cvv2 => "874",
:first_name => "Joe",
:last_name => "Shopper",
:billing_address => {
:line1 => "52 N Main ST",
:city => "Johnstown",
:state => "OH",
:postal_code => "43210",
:country_code => "US" }}}]},
:transactions => [{
:item_list => {
:items => [{
:name => "item",
:sku => "item",
:price => "1",
:currency => "USD",
:quantity => 1 }]},
:amount => {
:total => "1.00",
:currency => "USD" },
:description => "This is the payment transaction description." }]})
# Create Payment and return the status(true or false)
if #payment.create
#payment.id # Payment Id
else
#payment.error # Error Hash
end
This might be a good case for the Payouts API, which is also supported by the Ruby SDK.
To fund the payout with minimal fees, you'll want to have the payout amount already in your PayPal account or link to your bank account.

ruby-aws Amazon Mechanical Turk

I am trying to create a HIT with a pre-created form using the ruby-aws gem and keep getting a missing params error. I have limited the missing params to the params specific to my form.
It seems my request is not being formatted correctly and there are next to no examples from Amazon. My logs say the the following params are missing:
relationship, price, environmental_consciousness, age, occasion, gender, humor, experience, local, romance, additional_information
Any help is much appreciated!
Below is my current request:
hit = mturk.createHIT(
:Operation => 'CreateHIT',
:Title => 'Find a gift based on user scores',
:Description => 'Find a gift for an individual based on survey scores.',
:MaxAssignments => 3,
:Signature => signature,
:Timestamp => timestamp,
:Reward => { :Amount => 0.25, :CurrencyCode => 'USD' },
:HITLayoutId => '3AV6FF2M2GYMGLRQEKHZ7EBN4EZOJE',
:HitLayoutParameter => {'Name' => 'additional_information', 'Value' => 'TEST'},
:HitLayoutParameter => {'Name' => 'age', 'Value' => '22'},
:HitLayoutParameter => {'Name' => 'environmental_consciousness', 'Value' => '54'},
:HitLayoutParameter => {'Name' => 'experience', 'Value' => '32'},
:HitLayoutParameter => {'Name' => 'gender', 'Value' => 'male'},
:HitLayoutParameter => {'Name' => 'humor', 'Value' => '66'},
:HitLayoutParameter => {'Name' => 'local', 'Value' => '21'},
:HitLayoutParameter => {'Name' => 'occasion', 'Value' => '43'},
:HitLayoutParameter => {'Name' => 'price', 'Value' => '33'},
:HitLayoutParameter => {'Name' => 'relationship', 'Value' => '23'},
:HitLayoutParameter => {'Name' => 'romance', 'Value' => '23'},
:Keywords => 'data collection, gifting, gifts, shopping, gift listings, presents',
:AssignmentDurationInSeconds => 300,
:LifetimeInSeconds => 604800
)
I was able to resolive the issue - AWS has terrible naming conventions. The above example does use the correct format, however HitLayoutParameter must be HITLayoutParameter - Notice the CAPITAL HIT vs Hit.
Also, when submitting multiple parameters, the should only be one HITLayoutParameter that equals an array of Name/Value pairs. Working code below.
Hope this helps someone else!
Best,
~DFO~
hit = mturk.createHIT(
:Operation => 'CreateHIT',
:Title => 'Find a gift based on user scores',
:Description => 'Find a gift for an individual based on survey scores.',
:MaxAssignments => 3,
:Signature => signature,
:Timestamp => timestamp,
:Reward => { :Amount => 0.25, :CurrencyCode => 'USD' },
:HITLayoutId => '3AV6FF2M2GYMGLRQEKHZ7EBN4EZOJE',
:HITLayoutParameter => [
{:Name => 'additional_information', :Value => 'TEST'},
{:Name => 'age', :Value => '22'},
{:Name => 'environmental_consciousness', :Value => '54'},
{:Name => 'experience', :Value => '32'},
{:Name => 'gender', :Value => 'male'},
{:Name => 'humor', :Value => '66'},
{:Name => 'local', :Value => '21'},
{:Name => 'occasion', :Value => '43'},
{:Name => 'price', :Value => '33'},
{:Name => 'relationship', :Value => '23'},
{:Name => 'romance', :Value => '23'}
],
:Keywords => 'data collection, gifting, gifts, shopping, gift listings, presents',
:AssignmentDurationInSeconds => 300,
:LifetimeInSeconds => 604800
)

Tire :include_in_all => false but fields are still included in _all

I'm using tire for implementing search for a rails app.
The app is backed by CouchDB & couchrest_model gem, which implements ActiveModel.
From the readme it would seen that there's an option :include_in_all it's not explained as to it's behaviour but I'd presume the index would not be included when querying _all
Given the following mapping
mapping do
indexes :id, :index => 'not_analyzed', :include_in_all => false
indexes :title, :analyzer => 'snowball', :boost => 100
indexes :question_content, :analyzer => 'snowball'
indexes :skill_id, :index => 'not_analyzed', :include_in_all => false
indexes :topic_id, :index => 'not_analyzed', :include_in_all => false
indexes :archived, :type => 'boolean', :include_in_all => false
indexes :created_at, :type => 'date', :index => 'not_analyzed', :include_in_all => false
indexes :published_at, :type => 'date', :index => 'not_analyzed', :include_in_all => false
end
I'd expect ES to only search indexes for title and question_content when not specifying a default_field in a query.
Am I miss understanding or is this a bug?
//edit
deleting the index and re-creating it recognises the include_in_all options i've set.
Deleting the index and re-creating it recognises the include_in_all options i've set.

Resources