Return jsonb as rows in Postgres - arrays

I have a json column that holds an array of objects containing a 'name' attribute. I'm trying to build a query that can extract the unique names out of all the objects, across all rows.
Here is what the data looks like:
[{
"date": "2022-06-14T12:51:24.424Z",
"name": "review_1"
}]
[{
"date": "2022-06-14T12:50:56.454Z",
"name": "review_3"
}, {
"date": "2022-06-14T12:51:10.695Z",
"name": "review_6"
}]
[{
"date": "2022-06-14T12:51:57.997Z",
"name": "review_3"
}]
[{
"date": "2022-06-14T12:52:17.442Z",
"name": "review_1"
}, {
"date": "2022-06-14T12:54:35.239Z",
"name": "review_9
}]
My approach is to get all the names as individual rows like this so I can find the distincts.
name || date
review_1 2022-06-14T12:51:24.424Z
review_3 2022-06-14T12:50:56.454Z
review_6 2022-06-14T12:51:10.695Z
review_3 2022-06-14T12:51:57.997Z
review_1 2022-06-14T12:52:17.442Z
review_9 2022-06-14T12:54:35.239Z
I've tried using jsonb_array_elements following this post postgres + jsonb + get values of key from multidimentional array but it looks like that is for multidimentional arrays and I cannot get it to work.

It is hard to guess what kind of problems you have encountered, but the use of the function seems quite simple.
select elem->>'name' as "name", elem->>'date' as "date"
from my_table
cross join jsonb_array_elements(json_col) as arr(elem);
Test it in Db<>fiddle.

Related

How can I select a field and nested array from a JSON using JSONPath?

From the contacts, I'd like to select the values in fields: "Id" (47) and everything from the nested array [doNotContact]. I could use some help defining the JSONPath-filter I should be using to select the values: 47 and each value inside the nested array.
{
"total": "1",
"contacts": {
"47": {
"id": 47,
"isPublished": true,
"dateAdded": "2015-07-21T12:27:12-05:00",
"createdBy": 1,
"createdByUser": "Joe Smith",
"doNotContact": [{
"id": 2,
"reason": 2,
"comments": "",
"channel": "email",
"channelId": null
}]
}
}
}
I have tried paths like: $.contacts.*.['id','doNotContact'] however, this does not seem to work. I am using the website: https://goessner.net/articles/JsonPath/ normally this would help me solve the problem.
Not all implementations support the comma-delimited selectors, e.g. ['id','doNotContact']. See the JSON Path comparison project site (specifically this test) for information as to which implementations support the syntax.
Secondly, please see this answer about omitting the dot before a bracket syntax

Reading data from MongoDB that contains array using Talend

I have a collection in my MongoDB that contains one field that is an array.
Refer to the data above, the field 'Courses' is an array.
The JSON format of the data is like this:
{
"_id": {
"$oid": "60eb59b98a970a20865142e8"
},
"Name": "Sadia",
"Age": 24,
"Institute": "IBA",
"Courses": [{
"Name": "ITP",
"Grade": "A-"
}, {
"Name": "OOP",
"Grade": "A-"
}]
}
I am aware that there is a way in case its an object, but could not find a way on how to read this data using Talend since it contains an array.

Query an array of users based on an array of users

Basically I'm having trouble understanding how I would figure this out.
I have a document in a mongodb collection, and that document has field called friends which is an array of usernames.
I want to query through each username in the array friends, and have an array of those user documents. I'm terrible at explaining maybe if I draw this out it'll make sense.
mongodb document:
{
"_id": {
"$oid": "59a20e65f94cb5e924af774e"
},
"name": "Nick",
"friends": ["Jones","Mark","Mike"]
}
Now with this friends array, I want to search the same collection for an object with the "name" Jones, Mark, and Mike. When I find that object, I want to put it into an array.
Basically I want it to return this, (for this example let's say Jones, Mark, and Mike only have one friend, and that friend is Nick.
[{
"_id": {
"$oid": "59a20e65f94cb5e924af774e"
},
"name": "Jones",
"friends": ["Nick"]
},
{
"_id": {
"$oid": "59a20e65f94cb5e924af774e"
},
"name": "Mark",
"friends": ["Nick"]
},
{
"_id": {
"$oid": "59a20e65f94cb5e924af774e"
},
"name": "Mike",
"friends": ["Nick"]
}]
^ an array of three objects, which are all the friends of Nick.
If you need any more explanation please let me know, I'm terrible at this type of stuff.
For the record, I'm using node, and basic mongodb (not mongoose).
I believe you are looking for $in operator.
// doc.friends = ["Jones","Mark","Mike"]
db.collection.find({ name: { $in: doc.friends }})

Convert JSON to XML 'x' elements in array

I have a JSON array, which can contain several different elements in it - the number is unknown to me.
JSON:
[{
"_id": "5911a43e6aa5d609d32c590a",
"criteria": "3",
"name": "test1"
}, {
"_id": "5911a43e6aa5d609d32c590d",
"criteria": "7",
"name": "test2"
}, {
"_id": "5911a43e6aa5d609d32c5910",
"criteria": "2",
"name": "test3"
}]
I need to convert this data into XML, so that it is in the following structure:
<MyDefs criteria="3">
<name>test1</name>
</MyDefs>
<MyDefs criteria="7">
<name>test3</name>
</MyDefs>
<MyDefs criteria="2">
<name>test2</name>
</MyDefs>
I tried using xml2js node library- I assume I need a foreach loop but not sure how to implement - is there a way to achieve this?
Thank you

Identify documents in mongodb when matching two key:value pairs within a single array

I am trying to identify documents where both key-value pairs within an array match using the aggregate pipeline. Specifically, if I want to find documents where one array contains user_attribute.Name = Quests_In_Progress and user_attribute.Value =3. Below is an example of such a document that I'm trying to match.
If I use
db.myCollection.aggregate({
$match: {
"user_attribute.Name": "Quests_In_Progress",
"user_attribute.Value": "3"
}
})
It will match every document that contains Quests_In_Progress for user_attribute.Name in one element of the array and contains "3" for user_attribute.Value, regardless of whether they exist in the same element of the array or not.
i.e.
db.myCollection.aggregate({
$match: {
"user_attribute.Name": "Quests_In_Progress",
"user_attribute.Value": "0"
}
})
will match the same document simply because one element of the array has a key:Value pair of Value:0 and another element of the array contains a key:value pair of Quests_In_Progress.
What I want to do is identify documents where both of those conditions are met within one element of the array.
I tried to do this with $elemMatch, but I couldn't get it to work. Plus the aggregate documentation doesn't indicate that $elemMatch works, so maybe that's why I couldn't get it to work.
Lastly, I need to use the aggregate pipeline, because there are a bunch of other things I have to do after finding these documents- specifically unwinding them.
{
"_id": ObjectId("5555bb32de938ce667f78ce00"),
"user_attribute": [{
"Value": "Facebook",
"Name": "Social_Connection"
}, {
"Name": "Total_Fireteam_Missions_Initiated",
"Value": "0"
}, {
"Name": "Quests_Completed",
"Value": "3"
}, {
"Name": "Item_Slots_Owned",
"Value": "36"
}, {
"Name": "Quests_In_Progress",
"Value": "3"
}, {
"Name": "Player_Progression",
"Value": "0"
}, {
"Value": "1",
"Name": "Characters_Owned"
}, {
"Name": "Quests_Started",
"Value": "6"
}, {
"Name": "Total_Friends",
"Value": "0"
}, {
"Name": "Device_Type",
"Value": "Phone"
}]
}
Try using $elemMatch
db.myCollection.aggregate([{$match: {"user_attribute": {$elemMatch: {"Name":"Quests_In_Progress", "Value":"0"}}}}, { $out, "temp"}])
That query will find anyone who has element of their array "Quests_In_Progress" with a value of 0 and put it into the collection temp

Resources