Rails PSQL query JSON for nested array and objects - ruby-on-rails

So I have a json (in text field) and I'm using postgresql and I need to query the field but it's nested a bit deep. Here's the format:
[
{
"name":"First Things",
"items":[
{
"name":"Foo Bar Item 1",
"price":"10.00"
},
{
"name":"Foo Item 2",
"price":"20.00"
}
]
},
{
"name":"Second Things",
"items": [
{
"name":"Bar Item 3",
"price":"15.00"
}
]
}
]
And I need to query the name INSIDE the items node. I have tried some queries but to no avail, like:
.where('this_json::JSON #> [{"items": [{"name": ?}]}]', "%#{name}%"). How should I go about here?
I can query normal JSON format like this_json::JSON -> 'key' = ? but need help with this bit.

Here you need to use json_array_elements() twice, as your top level document contains array of json, than items key has array of sub documents. Sample psql query may be the following:
SELECT
item->>'name' AS item_name,
item->>'price' AS item_price
FROM t,
json_array_elements(t.v) js_val,
json_array_elements(js_val->'items') item;
where t - is the name of your table, v - name of your JSON column.

Related

Elasticsearch saves document as string of array, not array of strings

I am trying to contain array as a document value.
I succeed it in "tags" field as below;
This document contains array of strings.
curl -XGET localhost:9200/MY_INDEX/_doc/132328908
#=> {
"_index":"MY_INDEX",
"_type":"_doc",
"_id":"132328908",
"found":true,
"_source": {
"tags": ["food"]
}
}
However, when I am putting items in the same way as above,
the document is SOMETIMES like that;
curl -XGET localhost:9200/MY_INDEX/_doc/328098989
#=> {
"_index":"MY_INDEX",
"_type":"_doc",
"_id":"328098989",
"found":true,
"_source": {
"tags": "[\"food\"]"
}
}
This is string of array, not array of strings, which I expected.
"tags": "[\"food\"]"
It seems that this situation happens randomly and I could not predict it.
How could it happen?
Note:
・I use elasticsearch-ruby client to index a document.
This is my actual code;
es_client = Elasticsearch::Client.new url: MY_ENDPOINT
es_client.index(
index: MY_INDEX,
id: random_id, # defined elsewhere
body: {
doc: {
"tags": ["food"]
},
}
)
Thank you in advance.

Rails array style nested parms

So I have objects that I'm trying to pass to a json-acccepting restful interface using parms and #connection, but the source object and the target are in different formats, so I need to rename them.
So I'm trying to do something like this:
parms = {
:foo => anBunchOfBars.bar[
:barID => bar.Identifier
:bartab => bar.finances.owed
:barbell => bar.equipment.first
]
}
... to generate an outgoing JSON similar to the following:
{
"foo": [
{
"barID": "Irish Pub",
"bartab": "30 Yen",
"barbell": "Of the ball."
},
{
"barID": "One Gold Bar",
"bartab": "100 cents",
"barbell": "fry."
}
]
}
But I can't find the proper syntax. Examples I've found seem to only cycle through a core list and leave out naming items on nested traits (or skip nested traits entirely), and I haven't seen anything that shows how to pull values from a looped item.
What's the proper syntax to format the parms value?
Assuming that anBunchOfBars is an array of bars:
bars = anBunchOfBars.map do |bar|
{
barID: bar.Identifier
bartab: bar.finances.owed
barbell: bar.equipment.first
}
end
params = { foo: bars }

RoR - Find if part of a string matches an array of hashes

I know there are a lot of similar questions but I am struggling to find a specific answer.
i have an array of hashes with key of Symbol and a value of Price, I am looking to filter the array to only include the hashes that have a Symbol that ends in the letters ETL
Data looks like:
[ [
{
"symbol": "ABCDEF",
"price": "4"
},
{
"symbol": "GHIETL",
"price": "5"
}
]
You can use something like this:
array.select { |hash| hash[:symbol].end_with? "ETL" }
From the Ruby docs for select:
Returns an array containing all elements of enum for which the given block returns a true value.
You can also provide multiple suffixes to end_with? if you need to filter by multiple suffixes. For example:
array.select { |hash| hash[:symbol].end_with? "ETL", "DEF" }

Mongodb - search without key

I'd like to search documents in collection only by value. Let's say my collection contains documents like below:
[
{
"_id": "57a443c74d854d192afcc451",
"somekey": "123",
"otherkey": "zxc"
},
{
"_id": "57a443ca4d854d192afcc452",
"key": "123",
"otherkey": "123zxcvbnm"
}
]
and now I want to get all documents where value of any key contains 123.
I tried to do something like (written in Ruby and using mongoid):
new_search_query = { /.*/ => /#{v}/ }
collection.find(new_search_query)
but it looks like it is not suported becuase I get:
BSON::InvalidKey (Regexp instances are not allowed as keys in a BSON document.):
Is there any other manner or some workaround to do it?
Try full_text_search of mongoid for rails app.

Exclude fields from document in mongoid?

I have a Record model with many dynamic attributes. I want to make a request to the model an send the response as JSON to the client. But i want to exclude fields like _id and all foreign_keys in this model.
I found an interessting answer how to exclude the values of some keys: How do I exclude fields from an embedded document in Mongoid?, but the keys in the response still exists.
I got:
{
"_id": 1,
"name": "tom"
}
And the without method makes:
{
"_id": nil,
"name": "tom"
}
But i want:
{
"name": "tom"
}
Is it possible to remove or exclude some keys and the values from the result?
You don't want to remove fields from the mongoid document, what you want to do is remove fields from the generated json.
In your controller, do
render :json => #model.to_json(:except => :_id)
Documentation for the to_json method http://apidock.com/rails/ActiveRecord/Serialization/to_json
taken from the mongodb documentation at: http://docs.mongodb.org/manual/reference/method/db.collection.find/
Exclude Certain Fields from the Result Set
The following example selects documents that match a selection criteria and excludes a set of fields from the resulting documents:
db.products.find( { qty: { $gt: 25 } }, { _id: 0, qty: 0 } )
The query returns all the documents from the collection products where qty is greater than 25. The documents in the result set will contain all fields except the _id and qty fields, as in the following:
{ "item" : "pencil", "type" : "no.2" }
{ "item" : "bottle", "type" : "blue" }
{ "item" : "paper" }
i suppose mongoid is setting the _id attribute to nil since mongoid models have a defined set of attributes (even if they are dynamic, _id, _type etc are defined). maybe you can try it with the mongodb driver.
but i think RedXVII answer is the more practical way to go

Resources