Displaying Duplicate Records as One in Rails - activerecord

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

Related

Filtering products index in elasticsearch by user

I have an index of products. They have regular fields such as id, name, brand etc. Querying this index is working great, however I want to limit the products which are returned for specific users.
Say I have 5 products who’s IDs go from 1-5
Id: 1, name: “Product One”, brand: “Fake Brand”
Id: 2, name: “Product Two”, brand: “Fake Brand”
Id: 3, name: “Product Three”, brand: “Fake Brand”
Id: 4, name: “Product Four”, brand: “Fake Brand”
Id: 5, name: “Product Five”, brand: “Fake Brand”
If there’s no filter, and I search for brand: “Fake Brand”, I get 5 results.
But I want to add this functionality: Say I have two users. User 1 is only able to “see” product IDs 1, 2, and 5. And User 2 is only able to “see” a different subset, say, product IDs 1, 2, 4 and 5.
So if user 1 searches for brand: “Fake Brand”, he only gets back product with IDs 1, 2, and 5. Where as if user 2 searches for brand: “Fake Brand”, he only gets back products with IDs 1, 2, 4 and 5.
Is there a way to add a “user id” to this products query and then store somewhere else what products a user is able to see?
In SQL I would probably have a different table storing what products each user can see and then just do a join. But using ES I think I either have to have two separate indexes or to use nested or has_child/has_parent queries but I’m not entirely sure how to implement it.

fetch perticular number of documents satisfying multiple conditions - Elasticsearch

I have a Elasticsearch index for an information of fruits as below
GET fruits/fruits_data/_search
[{ id: 1,
name: apple},
{ id: 2,
name: mango},
{ id: 3,
name: apple},
{ id: 4,
name: banana},
{ id: 5,
name: apple},
{ id: 6,
name: mango},
{ id: 7,
name: pineapple},
{ id: 8,
name: jackfruit}]
Now I need to fetch 7 fruits as per the priority (below):
{"apple": 3, "banana": 3, "mango": 2, "guava": 2, "pineapple": 1, "jackfruit": 1}
Here the key indicates the fruit to be fetched and valueindicates the maximum number of the document to be fetched.
This means I need to fetch maximum 3 apple, 3 banana and 1 mango and I can ignore the others in priority hash when I have required number of fruits. But here I have only 1 banana in my ES index so I need to fetch maximum 3 apple, 1 banana, 2 mango and 1 pineapple (Since guava is not present in index we need to ignore it.
Is there a way to fetch fruits like this in ES in a single query. I don't want to use multiple queries.
Thanks
It is not possible to fetch results directly,Try using Aggregation in elasticsearch. You can refer to link below,
[https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html]

Search in Elasticsearch objects from non blocked user

In Elaasticsearch we have 3 collections, users, products and blocked_users.
user[
{id: 1, first_name: “John”, last_name:“Snow”, …}
{id: 2, first_name: “Sarah”, last_name:“Connor”, …}
{id: 2, first_name: “Arnold”, last_name:“Schwarzenegger”, …}
]
products[
{id: 1, user_id: 3, title:“Apple”}
]
blocked_users[
{user_id: 2, blocked_user_id: 3} // this mean user with id 2 blocked user with id 3
]
I want to search products by title, but I don't want to show products of blocked users.
So, when user with id 1 search he will get a response with 1 product
when user with id 2 search 0 products is expected, because product user id is 3, but user with id 2 blocked this user
How should be query?

How to delete RethinkDB documents that cannot be joined?

I have a tables Person and Property. Each one has its own id. In addition, properties have their human owner, hence have a field person_id which "points" to the id in the Person table.
This is an example of three people that have some things. For some reason, person with id=3 was deleted. However, he/she still owns properties with id in [4,5,6].
Person (1k documents)
=====================
{id: 1, name: John, age: 25}
{id: 2, name: Peter, age: 28, pet: cat}
{id: 4, name: Alice}
...
Property (120k documents)
=========================
{id: 1, person_id: 1, name: house}
{id: 2, person_id: 1, name: car, color: blue}
{id: 3, person_id: 2, name: phone}
{id: 4, person_id: 3, name: house}
{id: 5, person_id: 3, name: watch, size: big}
{id: 6, person_id: 3, name: table: material: wood}
...
The question is "How to delete the properties documents that no longer have an existing person they belong to?", i.e. in this case "How to delete properties with id in [4,5,6]?"
person_id is a secondary index.
My thoughs were like somehow extract the properties ids that don't match any persons and than delete them. However, I have no idea how to achieve that.

How to check for value in an array without iteration

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

Resources