I try to find a way of joining two nodes in Firebase (JSON based structure)
Example data structure:
"users" : {
"1" : {
"name" : "Example Name",
"contacts" : {
"2" : true,
"3" : true
},
"posts" : {
"15" : true,
"28" : true
}
},
"posts" : {
"5" : {
user : "2",
date_time : "11.11.2016",
text : "example text"
},
"15" : {
user : "1",
date_time : "25.11.2016",
text : "example text"
}
}
The user should now have a newsfeed screen, where all posts of all of his contacts are listed. Therefore a join of the two nodes would make the query much more efficient.
Right now I would execute a query for each contact to get the post id's and then have to do a final query to get the actual posts.
EDIT: details and question in comments
Related
I'm using Postgres 10.12, and I have a table (reels_data) that has a jsonb column called blocks, which is an array of objects, each with its own type and data object. Example:
[
{
"type" : "LOGO",
"data" : {
"imageId" : 399
}
},
{
"type" : "CONTACT_INFO",
"data" : {
"email" : "",
"phone" : "",
"url" : "",
"name" : "Bob",
"jobTitle" : "Developer"
}
},
{
"type" : "MEDIA",
"data" : {
"playlists" : [
{
"id" : "134e3b49-fe08-43b9-b13a-dc886ec0af61",
"name" : "Untitled Playlist",
"media" : [
{
"id" : 265,
"fileUuid" : "8a7519b8-92dc-4978-a239-5b25d66caf45",
"itemType" : "TRACK",
"name" : "Test",
"duration" : "104.749"
},
{
"id" : 266,
"fileUuid" : "7409bbd5-f8a0-46f2-a077-78c14a4dcd80",
"itemType" : "TRACK",
"name" : "Test 2",
"duration" : "144.163"
},
{
"id" : 267,
"fileUuid" : "14c0d325-bfce-4ac5-a4f6-3edaa0e86ac5",
"itemType" : "TRACK",
"name" : "Test 3",
"duration" : "143.871"
}
]
}
]
}
}
]
My challenge is, if a user deletes media with ID 265, it has to be pulled from all the blocks of type "MEDIA", and to make it more complicated, from all of the playlists in the playlists array.
These blocks can be in any order, so I can't assume an index of 2. And there could be one playlist or 10, and the media to remove could exist in none or several of these playlists.
Is there a single Postgres query I could write to remove all media of ID x? Or is this better written as a SQL query to simply retrieve the above data, add some data processing in JavaScript, and then a build & commit a SQL transaction to update several rows with new data? Efficiency is the top priority (not taxing the DB server).
Considering your structure is fixed, please try below query:
with cte as(
select
id,
data->'type' "type",
data->'data' "data",
playlists->>'id',
playlists->>'name',
jsonb_build_object('id', playlists->>'id','name', playlists->>'name', 'media',json_agg(z.media) ) "playlists"
from reels_data t1
left join lateral jsonb_array_elements(t1.blocks) x(data) on true
left join lateral jsonb_array_elements(x.data->'data'->'playlists') y(playlists) on true
left join lateral jsonb_array_elements(y.playlists->'media') z(media) on true
where z.media->>'id' is null or z.media->>'id' <>'265'
group by 1,2,3,4,5
),
cte1 as
(
select id,jsonb_agg(final) "final_data" from (
select
id,
type,
data,
playlists,
jsonb_build_object('type',type,'data',case when type='"MEDIA"' then jsonb_build_object('playlists',jsonb_agg(playlists)) else data end) "final"
from
cte
group by 1,2,3,4) t1
group by 1
)
update reels_data t1 set blocks= t2."final_data" from cte1 t2 where t1.id=t2.id
It will replace all the objects with given id.
DEMO
I have three Post in my collection of three different User
I am trying to fetch the post in my Views Session (Html, Css) Part
But I need to filter the other two post Posted from other two User
because I have some block functionality in my View Section. So all post are
allowed but the user I have blocked her/his post not visible to me and mine to him.
BlockedByUser : (This is my Post Json Data)
{
"_id" : ObjectId("591729b52bb30a19afc9b89d"),
"createdTime" : ISODate("2017-05-13T15:43:49.381Z"),
"isDeleted" : false,
"Message" : "Message Two",
"postedBy" : ObjectId("598adbefb3bf0b85f92edc3b"),
"recipient" : [
ObjectId("598ae453b3bf0b85f92ee331"),
ObjectId("5910691ae2bcdeab80e875f0")
],
"updatedTime" : ISODate("2017-05-20T09:24:39.124Z")
}
Below two user Post Data that I have blocked And
In his recipient Array Key stores my Id recipient [598adbefb3bf0b85f92edc3b]
Block User One :
{
"_id" : ObjectId("591729b52bb30a19afc9b89d"),
"createdTime" : ISODate("2017-05-13T15:43:49.381Z"),
"isDeleted" : false,
"Message" : "Message One",
"postedBy" : ObjectId("598ae453b3bf0b85f92ee331"),
"recipient" : [
ObjectId("598adbefb3bf0b85f92edc3b"),
ObjectId("5910691ae2bcdeab80e875f0"),
ObjectId("598ac93cb3bf0b85f92ece44"),
],
"updatedTime" : ISODate("2017-05-20T09:24:39.124Z")
}
Same as above
Block User Two :
{
"_id" : ObjectId("591729b52bb30a19afc9b89d"),
"createdTime" : ISODate("2017-05-13T15:43:49.381Z"),
"isDeleted" : false,
"Message" : "Message One",
"postedBy" : ObjectId("598ac93cb3bf0b85f92ece44"),
"recipient" : [
ObjectId("598adbefb3bf0b85f92edc3b"),
ObjectId("5910691ae2bcdeab80e875f0"),
ObjectId("598ae453b3bf0b85f92ee331")
],
"updatedTime" : ISODate("2017-05-20T09:24:39.124Z")
}
This is Block Collection that I have created and two blocked user Id with blockUserId key
Block Details One :
{
"_id" : ObjectId("598da2f0b88b0c2b0c735234"),
"blockUserId" : ObjectId("598ae453b3bf0b85f92ee331"),
"blockById" : ObjectId("598adbefb3bf0b85f92edc3b"),
"updatedDate" : ISODate("2017-08-11T12:28:32.145Z"),
"createdDate" : ISODate("2017-08-11T12:28:32.145Z"),
"isBlock" : "true",
"__v" : 0
Block Details Two
{
"_id" : ObjectId("598da558b88b0c2b0c735236"),
"blockUserId" : ObjectId("598ac93cb3bf0b85f92ece44"),
"blockById" : ObjectId("598adbefb3bf0b85f92edc3b"),
"updatedDate" : ISODate("2017-08-11T12:38:48.772Z"),
"createdDate" : ISODate("2017-08-11T12:38:48.772Z"),
"isBlock" : "true",
"__v" : 0
}
I have fetch these blocked collection and store two user blockUserId id in array
arrOne = ["598ae453b3bf0b85f92ee331", "598ac93cb3bf0b85f92ece44"]
And i am applying this query in mongoose db:
query = {$or: [{$and: [{ $or: [{ postedBy: req.params.id},
{recipient: req.params.id}
]
}, { createdTime: { $gt: endTime, $lt: startTime } }
]},{postedBy: {$ne: arrOne}}
]
};
}
But it will return undefined value
I am trying to fetch only my Post or Other user Post that not Blocked my Me, And Blocked User Post will not visible to me
I have to Implement where clause and it works
var query = { $and: [{ $or: [{ postedBy: req.params.id }, { recipient: req.params.id }] }, { "createdTime": { $gt: endTime, "$lt": startTime } }] };
CollectionName.find(query).where('postedBy').nin(blocklist).exec(function(err, response);
I have a the following json object --
{
"Title": "Terminator,
"Purchases": [
{"Country": "US", "Site": "iTunes"},
{"Country": "FR", "Site": "Google"}
]
}
Given the above object, here is how the search results show yield:
"Titles on iTunes in US" ==> YES, show "Terminator"
"Titles on Google in FR" ==> YES, show "Terminator"
"Titles on iTunes in FR" ==> NO
However, if I just AND the query, to get Titles with Purchase.Country="FR" and Titles with Purchase.Site="iTunes", it would erroneously show the above result, since both conditions are met. However, I want to restrict that facet to within the purchase item. The equivalent in python code would be:
for purchase in item['Purchases']:
if purchase['Country'] == "FR" and purchase['Site'] == "iTunes":
return True
Currently it works like this:
for purchase in item['Purchases']:
if purchase['Country'] == "FR":
has_fr = True
if purchase['Site'] == "iTunes":
has_itunes = True
if has_itunes and has_fr: return True
How would this be done in ElasticSearch?
First, you need to index the "Purchases" field as a nested field, by defining the mapping of your object type like this:
{
"properties" : {
"Purchases" : {
"type" : "nested",
"properties": {
"Country" : {"type": "string" },
"Site" : {"type": "string" }
}
}
}
}
Only then will ElasticSearch keep the association between the individual countries and the individual sites, as described here.
Next, you should use a nested query, such as this one:
{ "query":
{ "nested" : {
"path" : "Purchases",
"score_mode" : "avg",
"query" : {
"bool" : {
"must" : [
{
"match" : {"Purchases.Country" : "US"}
},
{
"match" : {"Purchases.Site" : "iTunes"}
}
]
}
}
}
}
}
This will return your object if the query combines "US" and "iTunes", but not if it combines "US" and "Google". The details are described here.
I have a mongo json object as follows
{
"_id" : new BinData(3, "RDHABb22XESWvP83FplqJw=="),
"name" : "NEW NODE",
"host" : null,
"aet" : null,
"studies" : ["1.3.12.2.1107.5.99.3.30000008061114424970500000589"],
"testcases" : [new BinData(3, "Zhl+zIXomkqAd8NIkRiTjQ==")],
"sendentries" : [{
"_id" : "1.3.12.2.1107.5.99.3.30000008061114424970500000589",
"Index" : 0,
"Type" : "Study"
}, {
"_id" : "cc7e1966-e885-4a9a-8077-c3489118938d",
"Index" : 1,
"Type" : "TestCase"
}]
}
The fields "Studies" and "TestCases" are now obsolete and I am now storing that information in a new field called SendEntries. I would like to get rid of the Studies and TestCases from the old entries and unmap those fields going forward. I want to know how I can update my current collections to get rid of the Studies and TestCases fields.
I'm just few weeks into Mongo.
You can use the $unset operator with update.
db.collection.update({},
{ $unset: {
"studies": "",
"testcases": ""
},
{ "upsert": false, "muti": true }
)
And that will remove all of the fields from all of your documents in your collection
Use $unset, there's a manual page e.g.
db.yourCollection.update( { },
{ $unset: {
Studies: "",
testcases: ""
}
},
{ multi: true }
)
I want to figure out the most active users on my site.
I have records of the form
{
"_id" : "db1855b0-f2f4-44eb-9dbb-81e27780c796",
"createdAt" : 1360497266621,
"profile" : { "name" : "test" },
"services" : { "resume":
{ "loginTokens" : [{
"token" : "82c01cb8-796a-4765-9366-d07c98c64f4d",
"when" : 1360497266624
},
{
"token" : "0e4bc0a4-e139-4804-8527-c416fb20f6b1",
"when" : 1360497474037
} ]
},
"twitter" : {
"accessToken" : "9314Sj9kKvSyosxTWPY5r57851C2ScZBCe",
"accessTokenSecret" : "UiDcJfOfjH7g9UiBEOBs",
"id" : 2933049,
"screenName" : "testname"
}
}
}
I want to be able to select users and order by the number of loginTokens.
In MySQL it would be something like:
SELECT id, COUNT(logins) AS logins
FROM users
GROUP BY id ORDER BY logins DESC
I've tried this on querymongo.com and i got an error (can't work with aliases/ cant order by non-column names)
What's the Mongo way to do this?
Thanks!
I just converted:
SELECT id, COUNT(logins)
FROM users
GROUP BY id
To:
db.users.group({
"key": {
"id": true
},
"initial": {
"countlogins": 0
},
"reduce": function(obj, prev) {
prev.countlogins++;
}
});
Hope this helps
Here is an example of what you said using the aggregation framework:
db.users.aggregate([
{$unwind: '$services.resume.loginTokens'},
{$group: {_id: '$_id', logins: {$sum: 1}}},
{$sort: {logins: -1}}
])
This should do the trick.