The background is I have a custom JSON based language.
Consider the following
In file 1, I have the following:
[
{
"name" : "abcde",
"source" : "source::abcde",
// other attributes
},
{
"name" : "qwerty",
"source" : "source::qwerty"
// other attributes
},
]
In file 2, I have the following:
abcde.json
{
"name" : "abcde"
// properties related to it
}
querty.json
{
"name" : "querty"
// properties related to it
}
Now, I want to build an extension/ grammar such that when a visitor uses Ctrl + click on source::abcde, it takes them to abcde.json.
I am wondering how to achieve through a VS code extension. I dont have a lot of expertise in this area.
I took a look into https://marketplace.visualstudio.com/ , could not find one directly. I have 10000+ such definitions, it is becoming very hard to maintain and update these.
Any help on how to achieve this? or some pointing blogs would be really helpful
Related
I am working on GraphQL mutation and need help here. My document looks like
{
"_id" : ObjectId("5bc02db357146d0c385d4988"),
"item_type" : "CategoryMapping",
"id" : null,
"CategoryGroupName" : "Mystries & Thriller",
"CustomCategory" : [
{
"name" : "Private Investigator",
"MappedBisacs" : [
"investigator",
"Privately owned",
"Secret"
]
},
{
"name" : "Crime Investigator",
"MappedBisacs" : [
"crime investigator",
"crime thriller"
]
}
]
}
UI
Allow user to update MappedBisacs through list of checkbox. So user can add/update or delete list of bisacs.
Problem - When client send GraphQL query like following;
mutation {
CategoryMapping_add(input: {CategoryGroupName: "Mystries & Thriller", CustomCategory: [{name: "Crime Investigator", MappedBisacs: ["investigator", "dafdfdaf", "dafsdf"]}]}) {
clientMutationId
}
}
I need to find Specific custom category and update its bisac array.
I am not sure if I got it, but this more a doubt on MongoDb than on GraphQL itself. First you must find the document that you want (I would use the id of the document instead of CategoryGroupName), then you can update this array in several ways. For example, after you found the document, you could simply access the array content and spread into a new one adding this new data from your mutation, and save this object with the update method. (if you simply want to add new data without removing any)
So, it depends on the case.
Check: https://docs.mongodb.com/manual/reference/operator/update-array/
Hope it helps! :)
I am triggering marketing goals using back-end code as follows:
if (!TrackerEnabled())
{
Tracker.StartTracking();
}
Item goal = Sitecore.Context.Database.GetItem(goalId);
var goalAsPageEvent = new PageEventItem(goal);
var pageEventsRow = Sitecore.Analytics.Tracker.CurrentPage.Register(goalAsPageEvent);
Sitecore.Analytics.Tracker.Submit();
And I can see the data in MongoDB interactions table as follows:
"PageEvents" : [
{
"Name" : "Apply Now - Auto Loans",
"Timestamp" : NumberLong(0),
"PageEventDefinitionId" : LUUID("dc9d7115-7bd5-7b40-9fa5-2722a2fb2e00"),
"IsGoal" : true,
"DateTime" : ISODate("2016-07-28T12:47:33.700Z"),
"Value" : 25
},
// ...
]
My question is: how can I see this data in Sitecore Experience Analytics or Content Editor?
Yes, you will be able to see this in Experience Analytics in aggregated state.
If you want to see this data in Sitecore with details you should use Experience Profile application.
I find that after upgrading to libraries to use 2.4.2 jackson-datatype-hibernate4 that most of the classes are being proxied correctly. But I also find that below classes show content as null in rendered json even though there is data.
UserPost
GroupPost
UserGroupPost
If I use projections then it is rendered / if I disable Hibernate proxies and enable JsonIgnoreProperties on "hibernateLazyInitializer" and "handler" , then also it is rendered.
Is their a possibility that Entities whose name is ending with Post are causing some kind of mixup ? I tested about 50 models and only find this happening with these Entities and are configured exactly like others and therefore am thinking in this direction ..
So when I go to /userGroupComments/12/userGroupPost I get below output, where UserGroupPost -> 1.* -> UserGroupComment
using Spring Data Rest , JPA latest builds(1.8.0.M1)
OUTPUT:
{
"content" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8080/app/userGroupPosts/4"
},
"userGroupComments" : {
"href" : "http://localhost:8080/app/userGroupPosts/4/userGroupComments"
},
"userPost" : {
"href" : "http://localhost:8080/app/userGroupPosts/4/userPost"
}
}
}
Links are correctly getting rendered but not the content. Entities are annotated with #AccessType(Type.PROPERTY) from org.springframework.data.annotation.AccessType
Take the following URI's as an example:
/tracks
/tracks/:id
/playlists
/playlists/:id
/playlists/:id/tracks
I have a question about the last URI (/playlists/:id/tracks). How do I add extra information/context to the track objects in relation to it's parent playlist?
Examples of context:
Added time of the track to the playlist
Play count of the track within the playlist
Likes per track within the playlist
All tracks have a created timestamp, play count and likes on a global scale. So my question is how would this information be added to the response of the endpoint.
I've come up with following for now:
{
"title" : "harder better faster stronger",
"artist" : "daft punk",
"likes" : 234252,
"created_at" : "2012-10-03 09:57:04"
"play_count" : 1203200035,
"relation_to_parent": {
"likes" : 5,
"created_at" : "2014-11-07 19:21:64",
"play_count" : 20
}
}
I've added a field called relation_to_parent which adds some context to the relation between the child and it's parent. I'm not sure though if this is a good way to do it. Hope to hear some other solutions.
By 1:n relations you can define a subresource. By n:m relations it is better to define a separate relationship resource. Note that these are just best practices, not standards.
Be aware that you can add links pointing to a different resource. According to the HATEOAS constraint you have to create hyperlinks if you want to expose an operation (for example getting another resource).
I don't think there is a 'one true way' to do this. Personally, I dislike adding the extra information like that, since you are giving a resource-plus, when you are looking for a resource. In any case, are 'likes' and 'created_at' and 'play_count' actually part of the relation to the parent, aren't they part of the track itself?
The two paths I usually see for this are:
/playlist/:id/tracks - returns a list of IDs (or URLs) for actual tracks, which you then fetch with /tracks/:track
/playlist/:id/tracks - returns the actual tracks, as if you did both steps in 1 above.
As for additional information, if it is not part of the tracks, you might do it as (any of these is valid):
info as part of the track, so /tracks/:track always returns the 'play_count' and 'likes', etc.
separate information, i.e. its own resource, if you want to keep the track clean. So you might get it at /tracks/:track/social_info or maybe /social_info/:track where it matches the track ID 1-to-1
If you have actual relation information, then it depends if it is 1:1 or 1:N or N:1 or N:N. 1:1 or 1:N or N:1 you would probably reports as part of the resource itself, while N:N would either be part of the resource (JSON objects can have depth) or as a separate resource.
Personally, I have done all of the above, and find cleaner is better, even if it is multiple retrievals. But now we are delving into opinion....
EDITED:
There are lots of ways to do N:N, here are just some:
/playlist/:id/tracks/:track/social_info - which could be embedded or a link to another object
/social_info/:playlist - more direct
/social_info/playlist/:id if you might have different kinds of social info
Personally (there is that word again; so much of this is personal preference and opinion), every time I have tried using deeper paths, thinking something only makes sense in a parent context, I have found myself ending up making its own resource for it, and linking back, so the 2nd or 3rd option ends up being what I do, with the first linking to it (either convenience to retrieve it or retrieve a list of it).
Mostly, that has not been because of constraints on the server side - e.g. when I write in nodejs, I use http://github.com/deitch/booster which handles multiple paths to the same resource really easily - but because client side frameworks often work better with a one true path.
If you want to fully embrace RESTful service design principles you definitely want to use hyperlinks in your representation format. JSON has some existing specifications if you prefer not to come up with your own: HAL and JSON API. A naive hypermedia format might look like this:
{
"playlist_id" : "666",
"created_at" : "2014-11-07 19:21:64",
"likes" : 5,
"tracks" : [
{"index" : 1,
"begin_at" : "00:02:00",
"end_at" : "00:05:23",
"_links" : {"track" : {
"href" : "/tracks/123",
"type" : "track"}}},
{"index" : 2,
"_links" : {"track" : {
"href" : "/tracks/432",
"type" : "track"}}},
{"index" : 3,
"_links" : {"track" : {
"href" : "/tracks/324",
"type" : "track"}}},
{"index" : 4,
"_links" : {"track" : {
"href" : "/tracks/567",
"type" : "track"}}}]
}
More elaborate features are included in both HAL and JSON API, like defining embedded resources and link templates. Using such semantics you might end up with something like the following:
{
"id" : "666",
"created_at" : "2014-11-07 19:21:64",
"likes" : 5,
"tracks" : [
{"id" : "123",
"index" : 1,
"begin_at" : "00:02:00",
"end_at" : "00:05:23"},
{"id" : "432",
"index" : 2},
{"id" : "324",
"index" : 3},
{"id" : "567",
"index" : 4}
],
"_links" : {
"_self" : {
"href" : "/playlists/666",
"type" : "playlist"},
"tracks" : {
"href" : "/tracks/{id}",
"type" : "track"}
},
"_embedded" : {
"track" : [
{"id" : "123",
"title" : "harder better faster stronger",
"artist" : "daft punk",
"created_at" : "2012-10-03 09:57:04",
"likes" : 234252,
"play_count" : 1203200035},
{"id" : "432",
"title" : "aerodynamic",
"artist" : "daft punk",
"created_at" : "2009-03-07 11:11:11",
"likes" : 33056,
"play_count" : 8796539}
]
}
}
Also, don't forget that using hyperlinks to express static relationships between entities is just the beginning of the journey. Using Hypermedia As The Engine Of Application State is the real Nirvana... but then you might be aiming too high.
Has anybody used MongoDB's Array type to implement a stack?
I know that I can append to an Array like so:
db.blogposts.update( {_id:5}, {$push: {comments: {by: "Abe", text:"First"}}})
Here, the end of the array is the top of the stack... I don't see a way to implement this with the top of the stack at the zero'th index, but I'd love to be wrong.
And I know that I can peek at the last value of the the array like so:
db.blogposts.find( {_id:5}, {comments: {$slice:-1}})
With an implementation like this, can I "peek" at the top of the stack in a MongoDB update statement? That would give me the semantic, "push this item on the stack if the top of the stack is X". I need this to be an atomic operation!
Any advice appreciated. Thanks!
Unfortunately, there is currently no way to do this exactly as you have described.
As Chris Shain pointed out, https://jira.mongodb.org/browse/SERVER-2191 - "$push() to front of array" and similarly https://jira.mongodb.org/browse/SERVER-1824 - "Support for inserting into specific array index" would help, but these features are currently not slated for a specific release version.
As a possible work-around, you could add a field named "lastElement" (or equivalent) to your document, which contains a copy of the last element pushed to the array. In your update statement, you could then query against the "lastElement" value, and if it matches, simultaneously set it to the new value and push the same value to the array in a single, atomic operation.
For example:
> db.blogposts.save({_id:5, comments:[{by: "Abe", text:"First"}], lastElement:{by: "Abe", text:"First"}})
> db.blogposts.find().pretty()
{
"_id" : 5,
"comments" : [
{
"by" : "Abe",
"text" : "First"
}
],
"lastElement" : {
"by" : "Abe",
"text" : "First"
}
}
> db.blogposts.update({"lastElement.text":"First"}, {$set:{lastElement:{by: "Joe", text:"Second"}}, $push:{comments:{by: "Joe", text:"Second"}}})
> db.blogposts.find().pretty()
{
"_id" : 5,
"comments" : [
{
"by" : "Abe",
"text" : "First"
},
{
"by" : "Joe",
"text" : "Second"
}
],
"lastElement" : {
"by" : "Joe",
"text" : "Second"
}
}
>
As an alternative, you may consider the strategy outlined in the "Update if Current" section of the "Atomic Operations" documentation: http://www.mongodb.org/display/DOCS/Atomic+Operations
I realize these are work-arounds and not ideal solutions. Hopefully the above will help you to accomplish your goal, or at least provide some food for thought for you to come up with a different solution. If you do, please share it here so that any members of the Community who may be experiencing similar issues may have the benefit of your experience. Thanks.
Looks like as of mongoDB v2.6, this is now supported via the $position operator: http://docs.mongodb.org/manual/reference/operator/update/position/
db.blogposts.update(
{_id:5}
, {$push:
{comments:
{$each: {by: "Abe", text:"First"}
, $position:0 }
}
}
);