How to check for value in an array without iteration - ruby

I want a single line of ruby (not using each) that will answer this question: Is there a follower_id of 2397558816 in this array?
myArray = [ #<Follower id: 1, username: "Prep Bootstrap", imageurl: "http://pbs.twimg.com//profile_images/2825468445/2a4...", user_id: "thefonso", follower_id: "2397558816", created_at: "2014-05-21 15:29:03", updated_at: "2014-05-21 15:29:03">, #<Follower id: 2, username: "JAVA Developer", imageurl: "http://pbs.twimg.com//profile_images/2825468445/2a4...", user_id: "thefonso", follower_id: "2352382640", created_at: "2014-05-21 15:29:05", updated_at: "2014-05-21 15:29:05"> ]
I am convinced that there must be a ruby method or combo of such that can do this. Can this be done?

You were on the right way: use Enumerable#any?:
myarray.any? { |v| v.follower_id == 2397558816 }

Note: This answer is based on assumption it is an ActiveRecord relation. If it is not, please comment and I'll remove this answer.
This is not a simple array, it is ActiveRecord::Relation object, which is a wrapper around an array. You should almost never use pure array objects on it, as this class is responsible for fetching objects from database. Using any? will fetch all the records from db and then iterate over it searching for match. Instead you should check it on a db lavel to limit number of fetched records (performance):
relation.exists?(follower_id: 2397558816)

(myArray.select {|elem| elem.instance_variable_get(:#id) == 1234567}) != []
Returns true if the array contains an element with the given id, and false if not

Related

Counting documents by property occurrence in Kibana

I'm trying to create a visualization that looks like this:
Foobar, 10
Bar, 8
Baz, 5.6
The first column is the aggregation itself. Imagine i have documents like this:
{
id: 1,
name: 'lorem ipsum',
type: 'A'
author: {
name: 'Foobar',
}
}
{
id: 2,
name: 'dolor sit amet',
type: 'B',
author: {
name: 'Foobar',
}
}
So, i want to add a +1 to the score of "Foobar" everytime i find a document of type A. And a +2 to the score if i find a document of type B. Basically, aggregating by the author name, and calculating a dynamic value on results.
Is this possible in Kibana? Thanks for the help.
AFAIK, you can't do this in Kibana in visualize panel, maybe you can try it in program then index the result into es.

Displaying Duplicate Records as One in Rails

I have a table of sales information, each product has twelve records for each month of the year. The only unique value is the sale total.
#<AccountMarginTarget id: 1, product_id: "123", sales: 2000>
#<AccountMarginTarget id: 2, product_id: "123", sales: 50>
#<AccountMarginTarget id: 2, product_id: "123", sales: 37>
#<AccountMarginTarget id: 2, product_id: "22", sales: 47>
#<AccountMarginTarget id: 2, product_id: "22", sales: 74>
I know I can retrieve consolodated data using .group, eg:
YearSales.group(:product_id).sum(:sale_total)
But when it comes to displaying all in the view, it's troublesome to have a list of 12 records. I've looked at .join .group .uniq etc. - but I'm still puzzled to as what the best method for only listing duplicates once?
Apologies for any naivety!
So, I've figured this out and feel a little dumb as to how easy it was to achieve. As I'm a Jr I'd appreciate any improvements on the below :) I'll update as my I review my code.
As I have many duplicates in my table, first I need to single them out
unique_ids = #sale_records.map(&:product_id).uniq.map
then I iterate through the unique_id's and retrieve the first result from the database that matches it:
#unique_product_sale_records = unique_ids.collect.each do | unique_id |
SalesRecord.where(product_id: unique_id).first
end

How to sort an array of mongoid documents (array contains different mongoid document types)?

I have two arrays of Mongoid documents, FirstType documents and SecondType documents. Both are embedded in User.
user.first_types = [#<FirstType _id: 51a10b4883c336ebef0002a8, created_at: 2013-05-25 19:04:40 UTC, updated_at: 2013-05-25 19:04:40 UTC, datetime: 2013-03-28 15:03:22 UTC, text: "Hello 1">]
user.second_types = [#<SecondType _id: 51a6058783c3368a62000003, created_at: 2013-05-29 13:41:27 UTC, updated_at: 2013-05-29 13:41:27 UTC, datetime: 2013-05-29 08:23:27 UTC, text: "Hello 2">]
Then I merge them with this line of code:
all_types = user.first_types+user.second_types
I now wish to sort the all_types array by the attribute datetime (newest datetime first, so the SecondType object should be the first one).
I have tried the conventional Mongoid and Ruby array methods, but they don't seem to work when I mix up Mongoid documents. Any ideas?
Use Enumerable#sort_by and negate the numeric value of the "datetime" attribute for descending order:
all_types.sort_by { |x| -x.datetime.to_f }

How do you calculate the average of a all entries in a field from a specific collection in Mongo using Ruby

Given the following data:
{
_id: ObjectId("51659dc99d62eedc1a000001"),
type: "image_search",
branch: "qa_media_discovery_feelobot",
time_elapsed: 19000,
test: "1365613930 All Media",
search_term: null,
env: "delta",
date: ISODate("2013-04-10T17:13:45.751Z")
}
I would like to run a command like:
avg_image_search_time = #coll.find("type" => "image_search").avg(:time_elapsed)
How would I accomplish this?
I understand the documentation on this is kind of difficult to follow.
avg_image_search_time = #coll.aggregate([ {"$group" => {"_id"=>"$type", "avg"=> {"$avg"=>"$time_elapsed"}}}, {"$match" => {"_id"=>"image_search"}} ]).first['avg']
To break this down:
We are grouping the matches by the type field, and returning the $avg time_elapsed for each type. We name the resulting average avg. Then, of those groups, filter out only the ones where the group _id matches image_search. Finally, since aggregate always returns an array, get the first result (there should only be one), and grab the avg field that we named.
Use the mongodb aggregation framework http://docs.mongodb.org/manual/core/aggregation/

Retrieving a Subset of Fields from MongoDB in Ruby

I'm trying to get a subset of fields from MongoDB with a query made in Ruby but it doesn't seem to work. It doesn't return any results
This is the ruby code:
coll.find("title" => 'Halo', :fields => ["title", "isrc"]) #this doesn't work
If I remove the fields hash, it works, returning the results with all the fields
coll.find("title" => 'Halo') #this works
Looking at the mongodb console the first query ends-up on the mongodb server like this:
{ title: "Halo", fields: [ "title", "isrc" ] }
If I try to make the query from the mongo client console, it works, I get the results and the subset. I make the query like this:
db.tracks.find({title: 'Halo'}, {title:1,isrc:1})
What could be the problem? I've been looking for a solution for this for a couple of hours now.
As of Sep, 2015, these other answers are outdated. You need to use the projection method: #projection(hash)
coll.find({"title" => 'Halo'}).projection({title: 1, isrc: 1})
The query should look like
collection.find(selector = {}, opts = {})
Query the database
In your case it is
coll.find({"title" => 'Halo'}, {:fields => ["title", "isrc"]})
But still remains a problem, the ruby-driver ignores the condition of "fields", and returns all the fields! :\
This query will return only the title and isrc for a doc that has the title "Halo":
coll.find({"title" => 'Halo'},{:fields => {"_id" => 0, "title" => 1, "isrc" => 1}})
Note the use of a Hash for the fields where the keys are the field names and the values are either 1 or 0, depending on whether you want to include or exclude the given field.
You can use the below query
coll.find({"title" => 'Halo'}).projection({title: 1, isrc: 1, _id: 0})
if you don't want _id, to be retrieved in case.

Resources