Creating this array format - ruby-on-rails-3

I need help in creating a json sting in the following format.
[{"key": "hello world", "value": "hello world"}, {"key": "movies", "value": "movies"}, {"key": "ski", "value": "ski"}, {"key": "snowbord", "value": "snowbord"}]
my input data will be categories with following attributes.
:id, :name, :active
and I would like to use the :id as key and :name as value.

input_data.map { |d| { "key" => d.id, "value" => d.name } }

Related

Transform JSON: select one row from array of json objects

I can't get a specific row from this JSON array.
So I want to get the object where filed 'type' is equal to 'No-Data'
Are there exist any functions in SQL to take the row or some expressions?
"metadata": { "value": "JABC" },
"force": false
"users": [
{ "id": "111", "comment": "aaa", type: "Data" },
{ "id": "222", "comment": "bbb" , type:"No-Data"},
{ "id": "333", "comment": "ccc", type:"Data" }
]
You can use a JSON path query:
select jsonb_path_query_first(the_column, '$.users[*] ? (#.type == "No-Data")')
from the_table
This assumes that the column is defined as jsonb (which it should be). If it's not you have to cast it: the_column::jsonb
Online example

Update one key value in JSON using Presto

I have a JSON column (_col0) like below and wanted to update only the 'name' part of json to new value.
{
"id":"1234",
"name":"Demo 1",
"attributes":[
{
"id": "1122",
"name": "affiliate",
"type": "number"
}
],
"behaviors": [
{
"id": "246685",
"name": "Email Send",
"scheduleOption": null,
"defaultTimeFilterEnabled": true,
"schema": []
}
]
}
I wanted to only change value of the outer "name" parameter from 'Demo 1' to 'Demo 2'. The SQL I tried does change the name parameter but makes the rest all to null.
select transform_values(cast(json_parse(_col0) as MAP(varchar, json)) , (k, v) -> if(k='name','Demo 2')) from table1
if has overload with 3 parameters, the 3rd being value for false case, use it to return the current value (you will need to transform either you varchar literal to json or json value to varchar):
-- sample data
WITH dataset (json_str) AS (
VALUES ('{
"id":"1234",
"name":"Demo 1",
"attributes":[
{
"id": "1122",
"name": "affiliate",
"type": "number"
}
],
"behaviors": [
{
"id": "246685",
"name": "Email Send",
"scheduleOption": null,
"defaultTimeFilterEnabled": true,
"schema": []
}
]
}')
)
-- query
select transform_values(
cast(json_parse(json_str) as MAP(varchar, json)),
(k, v)->if(k = 'name', cast('Demo 2' as json), v)
)
from dataset
Output:
_col0
{behaviors=[{"id":"246685","name":"Email Send","scheduleOption":null,"defaultTimeFilterEnabled":true,"schema":[]}], name="Demo 2", attributes=[{"id":"1122","name":"affiliate","type":"number"}], id="1234"}

Query the element in Array inside JSON column

I have a jason column in my postgress sql Database. I have several properties in that jason column. I can search properties using below query.
SELECT * FROM public.object_reference where value->>'name' = 'Sam' and value->>'address' ='home';
But my problem is I have a Array inside that JSON column. That Array has key and value pair. Below is the sample of that array
"attributes": [ {
"value": "Sam",
"key": "name"
}, {
"value": "abc",
"key": "address"
}, {
"value": "Singapore",
"key": "country"
}, {
"value": "97813245",
"key": "mobile"
}, {
"value": "Engineer",
"key": "position"
},
"id": "1312312",
"type": "Job",
"classid": "1245568956643546788907634"
}
So i need to get the value of name in the attributes array (inside JSON column). This is json type column, not a jsonb type.
You can deconstruct the array inside de object transforming it in a set of recordet (pseudo table) with json_array_elements:
select pair->>'value'
from has_json,json_array_elements(obj->'attributes') as pair
where pair->>'key' = 'name';
You can see a running example at: http://rextester.com/ONJZ8486

Apache Drill with mongodb. Query for documents with particular keys and values within a map

I use apache drill with mongodb. My documents in mongodb look like this:
{
"labels": [{
"key": "product",
"value": "shampoo"
},
{
"key": "id",
"value": "1"
},
{
"key": "number",
"value": "0"
}]
},
"labels": [{
"key": "product",
"value": "shampoo"
},
{
"key": "id",
"value": "2"
},
{
"key": "number",
"value": "1"
}]
}
And I want to query for documents which have e. g. a label {"key": "id", "value": "1"}
I tried it with this query:
select * from myCollection where `labels.key` = 'id' and `labels.value` = '1';
It should return only the first document, but it returns both, because the second document has a label with key = number and value = 1 (it is so because of the value).
Is there a possibility to obtain only the first document? How the query should look like?
Drill converts the collection to such table:
+---------------------------------------------------------------+
labels
+---------------------------------------------------------------+
[{"key": "product", "value": "shampoo"}, {"key": "id", "value": "1"},...]
[{"key": "product", "value": "shampoo"}, {"key": "id", "value": "2"}, ...]
+----------------------------------------------------------------+
This is not possible in Apache Drill.
In MongoDB you would express this criterion using the $elemMatch operator, for example:
db.collection.find(
{ labels: { $elemMatch: { key: "id", value: "1" } } }
)
However, Apache Drill's Mongo storage plugin does not support the $elemMatch operator.
The original documentation for Apache Drill's Mongo storage plugin stated:
As of now, predicate pushdown is implemented for the following filters: >, >=, <, <=, ==, !=, isNull and isNotNull.
Looking at the latest version of the code this remains the case so ... no support for $elemMatch and there is no relational operator which can perform this match for you.

Mongoid querying

I have some application on RoR with Mongodb database. I use Mongoid mapper. Model post.rb
class Post
include Mongoid::Document
field :title, :type => String
field :text, :type => String
embeds_many :comments
end
Model comment.rb
class Comment
include Mongoid::Document
field :name, :type => String
field :content, :type => String
embedded_in :post, :inverse_of => :comments
end
In database this post with some comment has next structure:
{
"_id": ObjectId("4ecbeacf65430f0cef000003"),
"comments": {
"0": {
"name": "my name",
"content": "example content",
"_id": ObjectId("4ecbead365430f0cef000005")
},
"1": {
"name": "some name",
"content": "example content",
"_id": ObjectId("4ecbead665430f0cef000007")
},
"2": {
"name": "some name",
"content": "example content",
"_id": ObjectId("4ecbeada65430f0cef000009")
}
},
"text": "example text",
"title": "example title"
}
And, for example, in database was a few posts with my comments.
I need to find all posts, where "name": "my name", i.e. I need to find all editable by me posts.
It should appear as a array of comments instead of a hash. See my example below.
Also, as per the mongoid docs use the new style field declarations.
comment.rb:
class Comment
include Mongoid::Document
field :name, type: String
field :content, type: String
embedded_in :post
end
post.rb:
class Post
include Mongoid::Document
field :title, type: String
field :text, type: String
embeds_many :comments
end
Rails Console:
p = Post.new(:title => "title", :text => "post")
c1 = Comment.new(:name => "Tyler", :comment => "Awesome Comment!")
c2 = Comment.new(:name => "Joe", :comment => "comment 2")
p.comments << c1
p.comments << c2
p.save
Mongo Console:
> db.posts.findOne()
{
"_id" : ObjectId("4ecd151d096f762149000001"),
"title" : "title",
"text" : "post body",
"comments" : [
{
"name" : "Tyler",
"comment" : "Awesome Comment!",
"_id" : ObjectId("4ecd1569096f762149000002")
},
{
"name" : "Joe",
"comment" : "comment 2",
"_id" : ObjectId("4ecd157f096f762149000003")
}
]}
Then, to do the query you want, which I think was "comments posted by me?":
> db.posts.findOne({"comments.name": "Tyler"})
Also, I would add an index to the comments.name field:
> db.posts.ensureIndex({"comments.name": 1})