Can I find item on database with given array of string but using partial string? - mysql

I have model Product with name and category
On seed:
Product.create(name: "apple", category: "food")
Product.create(name: "biogesic", category: "medicine")
And a 2 dimensional array:
[[1, "tray of apple", 150.00], [1, "box of ballpen", 70.30]]
What I need is to get if the string inside the array contains or is on the table/database Product
Here's what I'm thinking but I'm lost:
isProduct = Product.where("name like ?", "%an apple%").first
Where "%apple%" is supposed to be the string on array, but with that code it is limited for 1 word only.
I don't need the product id, I just need it if it is on the Product table.

In a certain way, this can be accomplished with the Regular Expression Operator ~ for PostgreSQL and/or REGEXP for MySQL:
regex = array.flat_map { |_, sentence, _| sentence.split }.join('|')
Product.exists?(['name ~ ?', regex])
Product.exists?(['name REGEXP ?', regex])
Which produces:
SELECT 1 AS one FROM "products" WHERE (name ~ 'tray|of|apple|box|of|ballpen') LIMIT $1 [["LIMIT", 1]]
As it searches for the presence of every single word within the sentences tray of apple and/or box of ballpen.
So, in case you have a record like:
Product.new(name: 'tray of apple and box of ballpen')
It'll cover the query and return true.

Related

How to get another key value from an array of json?

Lets say I have these arrayed JSON values
[{operation_id: 2, operation_name: FAITHFUL BELIEVERS},
{operation_id: 3, operation_name: SAMPLE OP},
{operation_id: 4, operation_name: SAMPLE OP 2}]
Now I will select the operation name 'SAMPLE OP' but I want to display the value of its operation_id. How would I do that?
Your JSON is a list of maps, so use where on the list to filter it by your predicate. Better still, use firstWhere as we assume there's just one match.
The match function returns true if the operation name member of the map matches.
firstWhere returns the first matching map, and you want the operation id member of that map.
final id = list
.firstWhere((m) => m['operation_name'] == 'SAMPLE OP')['operation_id'];

How can I loop with multiple conditional statements in OpenRefine (GREL)

I am geocoding using OpenRefine. I pulled data from OpenStreetMaps to my datasetstructure of data
I am adding a "column based on this column" for the coordinates.I want to check that the display_name contains "Rheinland-Pfalz" and if it does, I want to extract the latitude and longitude,i.e. pair.lat + ',' + pair.lon. I want to do this iteratively but I don't know how. I have tried the following:
if(display_name[0].contains("Rheinland-Pfalz"), with(value.parseJson()[0], pair, pair.lat + ',' + pair.lon),"nothing")
but I want to do this for each index [0] up to however many there are. I would appreciate if anyone could help.
Edit: Thanks for your answer b2m.
How would I extract the display_name corresponding to the coordinates that we get. I want the output to be display_name lat,lon for each match (i.e. contains "Rheinland-Pfalz", because I have a different column containing a piece of string that I want to match with the matches generated already.
For example, using b2m's code and incorporating the display_name in the output we get 2 matches:
Schaumburg, Balduinstein, Diez, Rhein-Lahn-Kreis, Rheinland-Pfalz, Deutschland 50.33948155,7.9784308849342604
Schaumburg, Horhausen, Flammersfeld, Landkreis Altenkirchen, Rheinland-Pfalz, Deutschland 52.622319,14.5865283
For each row, I have another string in a different column. Here the entry is "Rhein-Lahn-Kreis". I want to filter the two matches above to only keep those containing my string in the other column. In this case "Rhein-Lahn-Kreis" but the other column entry is different for each row. I hope this is clear and I would greatly appreciate any help
Assuming we have the following json data
[
{"display_name": "BW", "lat": 0, "lon": 1},
{"display_name": "NRW 1", "lat": 2, "long": 3},
{"display_name": "NRW 2", "lat": 4, "lon": 5}
]
You can extract the combined elements lat and long with forEach and filter using the following GREL expression e.g. in the Add column based on this column dialog.
forEach(
filter(
value.parseJson(), geodata, geodata.display_name.contains("NRW")
), el, el.lat + "," + el.lon)
.join(";")
This will result in a new field with the value 2,3;4,5.
You can then split the new multi valued field on the semicolon ";" to obtain separated values (2,3 and 4,5).
Another approach would be to split the JSON Array elements into separate rows, avoiding the forEach and filter functions.

Matching set of keywords to a string variable parsed from json

So I have a array of keywords such as
keyword = ['Bob','hello','boot']
I parsed json and grabbed string value named title and input into name.
Title contain strings such as "Bob hey, hello boot"
I am trying to make it so that program would return only true if Title/name contains all the words from keyword array list.
Currently, I have this code
keyword = ['Bob','hello','boot']
name=str(item[u'title'].encode('ascii','ignore')) #grab Title and input into name
found_a_string = True
for word in keyword:
if not word in name.lower():
found_a_string = False
if found_a_string:
ID=str(item[u'id'])
print name, ID, 'found' #would output full title and then assoicated ID from json.
But code return true as long as one of the words from keyword matche.
Any help would be appreciated.
Thanks
You can use all:
keyword = ['Bob','hello','boot']
name = "Bob hey, hello boot"
if all(x in name for x in keyword):
ID=str(item[u'id'])
print name, ID, 'found'

Get all tweets based on SPECIFIC word and STORE all tweets in SINGLE BAG

I am trying to process the sample tweet and store the tweets based on the filtered criteria.
For example,
sample tweet:-
{"created_time": "18:47:31 ", "text": "RT #Joey7Barton: ..give a word about whether the americans wins a Ryder cup. I mean surely he has slightly more important matters. #fami ...", "user_id": 450990391, "id": 252479809098223616, "created_date": "Sun Sep 30 2012"}
twitter = LOAD 'Tweet.json' USING JsonLoader('created_time:chararray, text:chararray, user_id:chararray, id:chararray, created_date:chararray');
grouped = GROUP twitter BY (text,id);
filtered =FOREACH grouped { row = FILTER $1 BY (text MATCHES '.*word.*'); GENERATE FLATTEN(row);}
it gets the complete tweets which matches with the word.
But I need to get the output as below:
(word)(all tweets of contained that word)
How can I achieve this?
Any help.
Mohan.V
After filtering add the word as a field say 'pattern' to the filtered relation and then group by that field.That will get you the word and a bag of tweets.
twitter = LOAD 'Tweet.json' USING JsonLoader('created_time:chararray, text:chararray, user_id:chararray, id:chararray, created_date:chararray');
grouped = GROUP twitter BY (text,id);
filtered = FILTER $1 BY (text MATCHES '.*word.*');
newfiltered = FOREACH filtered GENERATE 'word' AS pattern,filtered.text;
final = GROUP newfiltered BY pattern;
DUMP final;

How to use ransack to search MySQL JSON array in Rails 5

Rails 5 now support native JSON data type in MySQL, so if I have a column data that contains an array: ["a", "b", "c"], and I want to search if this column contains values, so basically I would like to have something like: data_json_cont: ["b"]. So can this query be built using ransack ?
Well I found quite some way to do this with Arrays(not sure about json contains for hash in mysq). First include this code in your active record model:
self.columns.select{|column| column.type == :json}.each do |column|
ransacker "#{column.name}_json_contains".to_sym,
args: [:parent, :ransacker_args] do |parent, args|
query_parts = args.map do |val|
"JSON_CONTAINS(#{column.name}, '#{val.to_json}')"
end
query = query_parts.join(" * ")
Arel.sql(query)
end
end
Then assuming you have class Shirt with column size, then you can do the following:
search = Shirt.ransack(
c: [{
a: {
'0' => {
name: 'size_json_contains',
ransacker_args: ["L", "XL"]
}
},
p: 'eq',
v: [1]
}]
)
search.result
It works as follows: It checks that the array stored in the json column contains all elements of the asked array, by getting the result of each json contains alone, then multiplying them all, and comparing them to arel predicate eq with 1 :) You can do the same with OR, by using bitwise OR instead of multiplication.