Check if value exist into array field mongoid rails - ruby-on-rails

I have a groups field in mongodb database
"groups" : "[\"5514efcc6970640f40150100\", \"5514efcc6970640f40160100\", \"5514efcc6970640f40170100\", \"5514efcc6970640f40180100\"]
Please suggest the query to check if field is exist into above database array.
like modelname.find(:groups=> 5514efcc6970640f40150100)

Looks like you actually have a string in groups, not an array. The string looks like you called inspect on an array of BSON ObjectIds in Ruby and stored that stringified array in MongoDB.
The leading double quote here:
⬇
"groups" : "[\"5514efcc6970640f40150100\", ...
⬆
tells you that you have a string. Inside that string you have what looks like an array of strings but it is still a string.
If that's really what you have then I think you're stuck with regex searches (which will be slow), something like:
Model.where(:groups => /"5514efcc6970640f40150100"/)
That assumes that all your groups strings are consistently formed and they are really stringified arrays of hexadecimal strings.
If this is the case then I'd suggest that you immediately fix your database and code so that you use real arrays in groups.
If your groups really is an array of hex strings like:
"groups" : ["5514efcc6970640f40150100", ...
then you can query it like a scalar field and let MongoDB unwrap the array for you:
Model.where(:groups => '5514efcc6970640f40150100')

Related

How to search using Activerecord in a json field stored as text in DB

I have a Json field stored in DB as text.
I want to look for records that contain Harvard as a value for those keys
json_data['infoOnProgram']['universityName']
How should I construct my where request to search on that Json field.
Student.where(json_data...
Thank you!
If there are a not very many records you can do this, which will be very expensive:
harvard_students = Student.map {|stud|
hash = JSON.parse(stud.json_data)
hash['infoOnProgram']['universityName'] == 'Harvard' ? stud : nil
}.compact
if you have lots and lots of records to iterate through you can limit your list with a regex query:
Simple
Student.where("json data like '%Harvard%'")
slightly better
Student.where("json data like '%infoOnProgram%universityName%Harvard%'")
The problem is without knowing how the data is structured it is hard to create a specific regex. You can use the where to limit and the iteration to confirm more precisely that these records are what you are looking for.
If you're sure you really do have valid JSON in your text column then you could cast it to jsonb (or json) and use the usual JSON operators and functions that PostgreSQL provides:
Student.where(
"json_data::jsonb -> 'infoOnProgram' ->> 'universityName' = ?",
'Harvard'
)
Student.where(
'json_data::jsonb -> :info ->> :name = :uni',
info: 'infoOnProgram',
name: 'universityName',
uni: 'Harvard'
)
Student.where(
'cast(json_data as jsonb) #>> array[:path] = :uni',
path: %w[infoOnProgram universityName],
uni: 'Harvard'
)
This is going to be an expensive query though as you won't be able to use any indexes. You really should start the process of changing the column's type to jsonb, that would validate the JSON, avoid having to type cast in queries, allow indexing, ...

How do I extract a field from an array of my models in order to form a single query?

I’m using Rails 4.2.7. I have an array of my model objects and currently I’m iterating through that array to find matching entries in the database based on a field my each object …
my_object_times.each_with_index do |my_object_time, index|
found_my_object_time = MyObjectTime.find_by_my_object_id_and_overall_rank(my_object_id, my_object_time.overall_rank)
My question is, how can I rewrite the above to run one query instead of N queries, if N is the size of the array. What I wanted was to force my underlying database (PostGres 9.5) to do a “IF VALUE IN (…)” type of query but I’m not sure how to extract all the attributes from my array and then pass them in appropriately to a query.
I would do something like this:
found_my_object_times = MyObjectTime.where(
object_id: my_object_id,
overall_rank: my_object_times.map(&:overall_rank)
)

Rails NOT IN query and regexp

I have array of strings:
a = ['*#foo.com', '*#bar.com', '*#baz.com']
I would like to query my model so I will get all the records where email isn't in any of above domains.
I could do:
Model.where.not(email: a)
If the list would be a list of strings but the list is more of a regexp.
It depends on your database adapter. You will probably be able to use raw SQL to write this type of query. For example in postgres you could do:
Model.where("email NOT SIMILAR TO '%#foo.com'")
I'm not saying thats exactly how you should be doing it but it's worth looking up your database's query language and see if anything matches your needs.
In your example you would have to join together your matchers as a single string and interpolate it into the query.
a = ['%#foo.com', '%#bar.com', '%#baz.com']
Model.where("email NOT SIMILAR TO ?", a.join("|"))
Use this code:
a = ['%#foo.com', '%#bar.com', '%#baz.com']
Model.where.not("email like ?",a.join("|"))
Replace * to % in array.

What is simplest way to convert :pluck or :collect results to array of strings in Rails?

I have a model called Record and belongs Product model,
the price column type is hexadecimal. Rails already convert it to string in view. But I wanna get them in my console queries.
Example code for pluck:
Product.first.records.pluck(:price)
This query displays the values in array as hexadecimal. There is a method called to_sentences for pluck values but its not enough for my case.
The problem is same in collect method:
Product.first.records.collect(&:price)
What is the pluck query to display my hexadecimal data as array of strings like:
["45,46","75,42"]
Product.first.records.pluck(:price).map(&:to_s)
please try this:
Product.first.records.pluck(:price).join(',')

Serialization/arrays in Rails 4

I'm using this line of code to create a serialization of type string:
serialize( :name, String)
I cannot access strings using :name[index] in my code , I can only access chars of a string when doing this over the console. Why is this so ? Shouldn't this method provide me with what I'm looking for ? I've seen that in Rails 4 you can use actual Array datatypes but it does not let me store my strings inside saying that they expected an Array datatype and not a String. Shouldn't Rails arrays be just arrays ready to store any type of data ?
What I want to do is just having an array of strings. Is this even the correct way of doing it ?

Resources