How to add/merge a nested JSON object that may or may not have parent nodes? - tsql

given the following set of selects :-
select JSON_MODIFY('{"A": {"X": 1}}', 'lax $.A.B',JSON_QUERY('{"K":1}'))
select JSON_MODIFY('{"A": {"X": 1, "B":{"E":1 }}}', 'lax $.A.B',JSON_QUERY('{"K":1}'))
select JSON_MODIFY('{"D": { "J": 1 }}', 'lax $.A.B',JSON_QUERY('{"K":1}'))
select JSON_MODIFY('{}', 'lax $.A.B',JSON_QUERY('{"K":1}'))
How do you modify the original json Object such that it adds or merges in
{"A": {"B": {"K" : 1}}}
with the existing JSON which may or may not have any or all of the path already existing.
from my examples :-
first one is correct
second one incorrectly overwrites the B tag
third one doesn't add anything
fourth doesn't add anything
Note: these are just examples, "K" in reality could be a whole other chunk of JSON that I want to merge into the "B" object without affecting other existing things on the "B" object.
Now I can imagine you could use "JSON_PATH_EXISTS" in a bunch of IIF clauses, but as the nesting gets deeper, this is going to be painful. I'm just wondering if I've missed some easy way to do this, or there is whole other approach to do this?

Related

RESTapi nesting endpoint

Ok, new to RESTapi so not sure if I am using the correct terminology for what I want to ask so bear with me. I believe what I am asking about is nested resources in a service but I want to ask specifically about using it for separating a blob of "closely related" content. It may be easier to provide an example. Let's say I have the following service that could output the following:
/Policy
"data": [ {
"name": "PolicyName1",
"description": "",
"size": 25000,
.... (bunch of other fields)
"specialEnablement": true,
“specialEnablementOptions”: { <-- options below valid only if specialEnablement is true
“optionType”: “TypeII”,
“optionFlagA”: false,
“optionFlagB”: true,
“optionFlagC”: false,
...(bunch of other options here)
}
},
{ . . . }],
The specialEnablementOptions are only used if specialEnablement is 'true'. It is all part of this /Policy service so has no primary key other than the policy "name" (and doesnt make sense to have to generate one) so does not fall under some of the other questions I have been reading about nested resources.
It does make it more readable to separate this set of information since there are 12 or so options but, this is REST so, maybe human readability does not weigh heavily here.
I am being told that, if we do it this way, it makes it more complex to work with during POST/PUT/PATCH commands. Specifically, it is being said in my group that if we do this, we should require two calls....one that creates the policy main information then the user must call a second time to PATCH the specialEnablementOptions (assuming specialEnablement is true). This seems kludgy to me.
I am looking for expert advise on what the best practice is.
My questions:
Does having the specialEnablementOptions nested in this way cause a
lot of complexity. Seems to me that either way we have to verify
that the settings are valid?
Does having the specialEnablementOptions nested in this way require
two calls? In other words, can a user not do a POST/PATCH/PUT for
all the fields including those in the specialEnablementOptions in
one call? We are planning to provide a way for the user to do a
PATCH of just the specialEnablementOptions options without changing
any of the first level for ease of use but is there something that
prevents them from creating or modifying all settings in one call?
Another option is to just get rid of the nested
specialEnablementOptions and put everything at the same level. I
dont have a problem with this but wasn't sure if this was just being
lazy. I dont mind doing this if the consensus is it is the best way
to do it....but I also have a second example that is similar to this
scenario but is a bit more complex where putting everything under the parent level is not really optimal (I will show in the next example)
So, my second example is as follows:
/anotherPolicy
"data": [ {
"name": "APolicyName1",
"description": "",
"count": 123,
"lastModified": "2022-05-17-20.37.27.000000",
[{
"ownerId": 1
"ownerCount": 1818181
"specialFlags": 'ABA'
},
{ . . . }]
},
{ . . . }],
The above 'count' is the total number associated to that policy and then there is a nested resource by owner where the count by owner can be seen..plus maybe other information specific to that owner. The SUM(ownerCount) would equal "count" above it. Does this scenario change any of the answers to the questions above?
I appreciate your help. I found a ton of information and reference on when to use or not use nested endpoints but all the examples seem to orient around subjects that seem like they could easily be separated into two resource...for instance whether to nest /employees under /departments or /comments under /posts. Also, they didn't deal with the complexities of having nested endpoints vs avoiding them. And last, if using nesting is unnecessary as a readability standpoint.

What would I call the things inside a document in MongoDB?

I havent really ran into a error, but I was wondering. MongoDB calls each thing inside a collection a "document" I was wondering what you call the things inside a document.
Ok, after looking for a long time. This is what you call the things inside a document. Its called a field.
#this entire thing is called a document.
#The fields in this document are: name, age, status, and groups.
#The values in this document are: "sue", 26, "A", and ["news", "sports"]
Hope this helps anyone who had the same question as me!
{
name: "sue",
age: 26,
status "A",
groups: ["news", "sports"]
}

RESTful reordering of nested objects

I have a RESTful API that supports two objects so as object A contains an ordered list of nested objects B:
Create object A - POST /a
Create object B and add to A - POST /a/<id>/b
Update object B in A - PATCH /a/<id>/b/<id>
What would be a RESTful way to update the order of B objects in a specific A?
Option 1: PATCH /a/<id> with json content that replaces A.Bs
A has a list of embedded Bs, namely A.Bs so you can replace that list in its entirety also changing the order on the way. This relies on the client to resubmit the entire list correctly.
Option 2: PATCH /a/<id> with json content that replaces A.B_order
Add a separate list of B ids and have the client update it. This is similar to Option 1 but does not rely on the client resubmitting all the objects. It does require the server to manage the list, updating it upon B creation, and validating the update contains all the required B ids on list order update.
Option 3: PATCH /a/<id>/b with json content that replaces A.Bs
The same as Option 1, but with a different URL
Which would be most RESTful and clear?
Any other options?
I would suggest using the proposed standard defined in RFC 6902. Specifically, the "move" op would seem to be what you're looking for.
Given Foo has Bars and Bars are resources (have ID or link), when you need to reorder foo.bars then I would suggest:
’PUT /foos/:id/bars’ with array of IDs or links in the body.
But if Bars are not resources (have no ID), then:
’PATCH /foos/:id’ with body of Foo including complete new array of Foo.bars in the ’bars’ property.
The question I would ask myself is: "What does 'order' mean in this case".
The specific instances of B don't have an order between them. They're all independent resources that are not really 'aware' of each order.
Given that, it's not really the B resource that you are changing. What are you changing?
Presumably there is a collection of B's somewhere. You do a GET request on that collection to get an ordered list of B's. Do you get that list on /a/<id> or on /a/<id>/b ?.
Wherever that ordered list is, I would also do the operation to change the order because the order is a 'property' of the collection.
So for the sake of the argument, lets assume that your 'collection of B lives on /a/<id>b. What format should that be?
Well, a good REST service will replace the entire state. So as a default I would do a PUT request on that resource and do a full replace of the entire thing.
If you don't like that idea and want to use PATCH to update only a part of the collection (and nothing else), I think I would opt for one of these:
Use a standard format, like json-patch.
Come up with your own syntax to describe this.
Option 2 will likely be a lot simpler to implement, and I would also keep the format as simple as possible.
If you use a format like HAL, a collection is probably a list of links. In that case I would use a syntax like:
{
"_links": {
"item": [
{ "href": "/a/<id>/b/ordered-item-1" },
{ "href": "/a/<id>/b/ordered-item-2" }
]
}
}
If you don't have a hypermedia-style API, you probably use id's and force the client to expand id's in urls. In that case, I'd imagine the format could look like:
{
"items": [ 1, 3, 5, 2]
}
In each case, it's a Good Idea to define your own media type for this, because this format for PATCH has special meaning to your api. For example:
application/vnd.jonathan.patch+json

MongoDB get last 10 activities

In My social network I want to get the feed for member A , member A is following lets say 20 category/member.
when a category/member(followed by member A) do an activity it is inserted into a collection called recent_activity :
{
"content_id": "6", // content id member A is following
"content_type_id": "6",// content type (category , other member)
"social_network_id": "2", // the action category did (add/like/follow)
"member_id": "51758", //Member A
"date_added": ISODate("2014-03-23T11:37:03.0Z"),
"platform_id": NumberInt(2),
"_id": ObjectId("532ec75f6b1f76fa2d8b457b"),
"_type": {
"0": "Altibbi_Mongo_RecentActivity"
}
}
I want when member A login into the system to get last 10 activities for the categories/member
my problem :
How to get Only 10 activities for all categories/members.
It is better to do it in one query or to do a for loop.
For this use case, I'd suggest to invert the logic and keep a separate object of the last 10 activities for member A that is kept up-to-date all the time. While that solution is more write-heavy, it makes reading trivially simple and it can be extended very easily. I'd like to blatantly advertise a blog post I wrote a while ago about news feeds with mongodb which outlines this approach.
This 'fan-out' approach might seem overly complex at first, but when you think about importance filtering / ranking (a la facebook), push messages for particularly important events (facebook, twitter) or regular digest emails (practically all), you will get one location in your code to perform all this logic.
I think I commented that T'm not really seeing the selection criteria. So if you are "outside" of a single collection, then you have problems. But if your indicated fields are the things you want to "filter" by, then just do this:
db.collection.find({
"social_network_id": "2",
"content_type_id": "6",
"content_id": "6",
"member_id": { "$ne": "51758" }
})
.sort({ "$natural": -1 })
.limit(10);
So what does that do? You match the various conditions in the data to do the "category match" (if I understood what was meant), then you make sure you are not matching entries by the same member.
The last parts do the "natural" sort. This is important because the ObjectId is monotinic, or math speak for "ever increasing". This means the "newest" entries are always the "highest" value. So descending order is "latest" to "oldest".
And the very final part is a basic "limit". So just return the last 10 entries.
As long as you can "filter" within the same collection in whatever way you want, then this should be fine.

How to escape some characters in postgresql

I have this data in one column in postgresql
{
"geometry":{
"status":"Point",
"coordinates":[
-122.421583,
37.795027
]
},
and i using his query
select * from students where data_json LIKE '%status%' ;
Above query return results but this one does not
select * from students where data_json LIKE '%status:%' ;
How can fix that
Of course the 2nd one doesn't find a match, there's no status: text in the value. I think you wanted:
select * from students where data_json LIKE '%"status":%'
... however, like most cases where you attempt text pattern matching on structured data this is in general a terrible idea that will bite you. Just a couple of problem examples:
{
"somekey": "the value is \"status\": true"
}
... where "status": appears as part of the text value and will match even though it shouldn't, and:
{
status : "blah"
}
where status has no quotes and a space between the quotes and colon. As far as JavaScript is concerned this is the same as "status": but it won't match.
If you're trying to find fields within json or extract fields from json, do it with a json parser. PL/V8 may be of interest, or the json libraries available for tools like pl/perl, pl/pythonu, etc. Future PostgreSQL versions will have functions to get a json key by path, test if a json value exists, etc, but 9.2 does not.
At this point you might be thinking "why don't I use regular expressions". Don't go there, you do not want to try to write a full JSON parser in regex. this blog entry is somewhat relevant.