ALPS sample implementation - rest

I'm looking for a sample client implementation utilizing ALPS (not the mountains but the Application-Level Profile Semantics).
Do YOU! have one?
I've looked into the related RFC draft and discussions but still can figure it quite out.
Specifically I would like to know how my client should know what the descriptor describes, given that my client supposedly knows nothing about the structure and semantics of the REST API as the REST principle demands?
As a human I know that a descriptor with an id tag called "users" is likely to describe how to interact with users but how is my client to know without me telling him explicitly?
I know I could insert some kind of keyword to show up in the descriptor and tell my client to match the appropriate ones but this seems hardly the right way.
I happily provide a more detailed example given somebody is willing to read it.

I'm exploring ALPS for the first time too, and my understanding from that RFC draft wasn't immediate either.
Here is a slideshow (166 slides, so it's not possible to copy it all into this answer) from the author of the RFC which I think gives a much better understanding of the role ALPS plays.
As a human I know that a descriptor with an id tag called users is likely to describe how to interact with users but how is my client to know this without me telling him explicitly?
From this slideshow, I deduce this answer to your question: He doesn't.
In the slideshow, a sample ALPS profile is compared with equivalent HTML code for a form submit. The browser knows how to render the HTML to the screen, but only the human knows what it means to POST that form with those input fields, using that submit button.
Here is an example Complete JSON Representation taken from alps.io
{
"alps" : {
"version" : "1.0",
"doc" : {
"href" : "http://example.org/samples/full/doc.html"
},
"descriptor" : [
{
"id" : "search",
"type" : "safe",
"doc" : {"value" :
"A search form with a two inputs"
},
"descriptor" : [
{
"id" : "value",
"name" : "search",
"type" : "descriptor",
"doc" : { "value" : "input for search" }
},
{ "href" : "#resultType" }
]
},
{
"id" : "resultType",
"type" : "descriptor",
"description" : {"value" : "results format"},
"ext" : [
{
"href" : "http://alps.io/ext/range",
"value" : "summary,detail"
}
]
}
]
}
}
Take, for example, a generic mobile phone app which is displaying screens to the user based on REST responses. Say a HAL+Json response contains a reference to a search entity. The app can lookup in this ALPS document what a search entity is, and can be coded on how to represent that. Namely, a search is something which has a name/value pair (with an id) and a href. The href refers to the second descriptor with id resultType which lets the app know the format to expect for search results. The actual URLs and data involved would come from the REST responses.
From July 2014, here is a Spring blog article describing the ALPS for an app which manages a "To Do List". The ALPS document describes
What is a todo entity
What actions can be done with a todo entity
An abridged version of the ALPS profile for that small app:
{
"version" : "1.0",
"descriptors" : [ {
"id" : "todo-representation",
"descriptors" : [ {
"name" : "description",
"doc" : {
"value" : "Details about the TODO item",
"format" : "TEXT"
},
"type" : "SEMANTIC"
}, {
"name" : "title",
"doc" : {
"value" : "Title for the TODO item",
"format" : "TEXT"
},
"type" : "SEMANTIC"
}, {
"name" : "id",
"type" : "SEMANTIC"
}, {
"name" : "completed",
"doc" : {
"value" : "Is it completed?",
"format" : "TEXT"
},
"type" : "SEMANTIC"
} ]
}, {
"id" : "create-todos",
"name" : "todos",
"type" : "UNSAFE",
"rt" : "#todo-representation"
}, {
"id" : "get-todos",
"name" : "todos",
"type" : "SAFE",
"rt" : "#todo-representation"
}, {
"id" : "delete-todo",
"name" : "todo",
"type" : "IDEMPOTENT",
"rt" : "#todo-representation"
} ]
}
I guess one way to think of it might as a kind "schema", but instead of database tables, it's describing the scope of REST responses.

Related

MongoDB: Is it possible to index(unique) subarrays from documents in an isolated way?

I recently encountered an issue, and I'd like to solve it. If anyone would give any suggestion I'll be grateful.
I have documents that represent "users" and each document has a subarray that is responsible to save some codes, they can be many for each user. The matter is, each user cannot have duplicate codes in its specific array, but at the same time, in this case, each document should be isolated, for example, being possible to have two or more identical codes but since they are from different documents(users).
In short, the subarray("codes") cannot have individually duplicated codes(code), but that shouldn't interfere with other documents
I could do that in the application part, but I think doing that guarantee directly on DB, it's safer.
Is it possible to create indexes for this specific situation?
Example of two documents representing their respective users:
{ // Document of user 1
"_id" : "1", //user 1 and its codes
"codes" : [
{
"code" : "1111",
"description" : "code 1",
},
{
"code" : "2222",
"description" : "code 2",
},
{
"code" : "3333",
"description" : "code 3",
}
]
},
{ // Document of user 2
"_id" : "2", //user 2 and its codes
"codes" : [
{
"code" : "1111",
"description" : "code 1",
},
{
"code" : "4444",
"description" : "code 2",
},
{
"code" : "2222",
"description" : "code 3",
}
]
}
Thank you!
Use https://docs.mongodb.com/manual/reference/operator/update/addToSet/ to maintain uniqueness of code subdocuments. You will need to ensure that you always specify code fields in the same order (e.g. code, description).

Relation N to N mongodb. Embedded or reference?

I'm newbie in mongodb. Suppose I have the following:
In this case, I have a relation N to N between Posts an tags. Because 1 Post could be have several tags associated and vice versa.
Post
{
"_id" : ObjectId("508d27069cc1ae293b36928d"),
"title" : "This is the title",
"body" : "This is the body text.",
"tags" : [
"chocolate",
"spleen",
"piano",
"spatula"
],
"created_date" : ISODate("2012-10-28T12:41:39.110Z"),
"author_id" : ObjectId("508d280e9cc1ae293b36928e"),
"category_id" : ObjectId("508d29709cc1ae293b369295"),
"comments" : [
{
"subject" : "This is coment 1",
"body" : "This is the body of comment 1.",
"author_id" : ObjectId("508d345f9cc1ae293b369296"),
"created_date" : ISODate("2012-10-28T13:34:23.929Z")
},
{
"subject" : "This is coment 2",
"body" : "This is the body of comment 2.",
"author_id" : ObjectId("508d34739cc1ae293b369297"),
"created_date" : ISODate("2012-10-28T13:34:43.192Z")
},
{
"subject" : "This is coment 3",
"body" : "This is the body of comment 3.",
"author_id" : ObjectId("508d34839cc1ae293b369298"),
"created_date" : ISODate("2012-10-28T13:34:59.336Z")
}
]
}
Let's say I have to change a specific tag, for instance: replace "chocolate" by "choco". Probably, There will have a lot of posts with the tag "chocolate".
Is this approach embedded the correct one or Do I have to implement reference?
If you expect that a value that is used in multiple locations may need to be changed you'll need to use it by reference. IE in your case if you have a ton of posts with the chocolate and you need to replace it with choco, it will be very inefficient (and a little bit risky) if the tags are embedded. However if its all done by reference you just need to change chocolate to choco in one place.
StackOverflow actually does this. Question tags may be renamed and it will instantly rename all the instances of the tag. This is done easily by StackOverflow though because they use relational SQL databases in the backed.
Which leads me to my final point - if you expect to need a lot of reference data you should really reconsider using Mongo. When your data has a lot of reference relations, you probably want to use a relational database.

mongodb: taking a set of keys from one collection and matching with another

I'm new to mongodb and javascript, and have been reading the manual, but I can't seem to put the pieces together to solve the following problem.. I was wondering if you can kindly help.
I have two collections "places" and "reviews".
One document in "places" collection is as follows:
{
"_id" : "004571a7-afe4-4124-996e-b6ec779db494",
"name" : "wakawaka place",
"address" : {
"address" : "12 ad avenue",
"city" : "New York",
},
"review" : [
{
"id" : "i32347",
"review_list" : [
"r123456",
"r123457"
],
}
]
}
The "review" array can be empty for some documents.
And in the "reviews" collection, every document in the collection represents a review:
{
"_id" : ObjectId("53c913689c8e91a5a9c4047f"),
"user_id" : "useridhere",
"review_id" : "r123456",
"attraction_id" : "i32347",
"content" : "review content here"
}
What I would like to achieve is, for each place that has reviews, get the content of each review from the "review" collection and store them together in another new collection.
I'd be grateful for any suggestions on how to go about this.
Thanks

want to merge two collection in mongo db using map reduce

I have two collection as bellow products has reference of user. i search product by name & in return i want combine output of product and user using map reduce method
user collection
{
"_id" : ObjectId("52ac5dd1fb670c2007000000"),
"company" : {
"about" : "This is textile machinery dealer",
"contactAddress" : [{
"address" : "abcd",
"city" : "52ac4bc6fb670c1007000000",
"zipcode" : "39as46as80"
},{
"address" : "abcd",
"city" : "52ac4bc6fb670c1007000000",
"zipcode" : "39as46as80"
}],
"fax" : "58784868",
"mainProducts" : "ads,asd,asd",
"mobileNumber" : "9537236588",
"name" : "krishna steels",
}
"user" : ObjectId("52ac4eb7fb670c0c07000000")
}
product colletion
{
"_id" : ObjectId("52ac5722fb670cf806000002"),
"category" : "52a2a9cc48a508b80e00001d",
"deliveryTime" : "10 days after received the ",
"price" : {
"minPrice" : "2000",
"maxPrice" : "3000",
"perUnit" : "5288ac6f7c104203e0976851",
"currency" : "INR"
},
"productName" : "New Mobile Solar Charger with Carabiner",
"rejectReason" : "",
"status" : 1,
"user" : ObjectId("52ac4eb7fb670c0c07000000")
}
This cannot be done. Mongo support Map Reduce only on one collection. You could try to fetch and merge in a java collection. Couple of days back I solved a similar problem using java collection.
Click to see similar response about joins and multi collection not supported in mongo.
This can be done using two map reduces.
You run your first MR and then you reduce out the second MR onto the results of the first.
You shouldn't do this though. JOINs are not designed to be done through MR, in fact it sounds like you are trying to do this MR with inline output which in itself is a very bad idea.
MRs are not designed to run inline to the application.
You would be better off doing the JOIN else where.

Get nested fields with MongoDB shell

I've "users" collection with a "watchlists" field, which have many inner fields too, one of that is "arrangeable_values" (the second field within "watchlists").
I need to find for each user in "users" collection, each "arrangeable_values" within "watchlists".
How can I do that with mongodb shell ?
Here is an example of data model :
> db.users.findOne({'nickname': 'superj'})
{
"_id" : ObjectId("4f6c42f6018a590001000001"),
"nickname" : "superj",
"provider" : "github",
"user_hash" : null,
"watchlists" : [
{
"_id" : ObjectId("4f6c42f7018a590001000002"),
"arrangeable_values" : {
"description" : "My introduction presentation to node.js along with sample code at various stages of building a simple RESTful web service with journey, cradle, winston, optimist, and http-console.",
"tag" : "",
"html_url" : "https://github.com/indexzero/nodejs-intro"
},
"avatar_url" : "https://secure.gravatar.com/avatar/d43e8ea63b61e7669ded5b9d3c2e980f?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png",
"created_at" : ISODate("2011-02-01T10:20:29Z"),
"description" : "My introduction presentation to node.js along with sample code at various stages of building a simple RESTful web service with journey, cradle, winston, optimist, and http-console.",
"fork_" : false,
"forks" : 13,
"html_url" : "https://github.com/indexzero/nodejs-intro",
"pushed_at" : ISODate("2011-09-12T17:54:58Z"),
"searchable_values" : [
"description:my",
"description:introduction",
"description:presentation",
"html_url:indexzero",
"html_url:nodejs",
"html_url:intro"
],
"tags_array" : [ ],
"watchers" : 75
},
{
"_id" : ObjectId("4f6c42f7018a590001000003"),
"arrangeable_values" : {
"description" : "A Backbone alternative idea",
"tag" : "",
"html_url" : "https://github.com/maccman/spine.todos"
},
"avatar_url" : "https://secure.gravatar.com/avatar/baf018e2cc4616e4776d323215c7136c?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png",
"created_at" : ISODate("2011-03-18T11:03:42Z"),
"description" : "A Backbone alternative idea",
"fork_" : false,
"forks" : 31,
"html_url" : "https://github.com/maccman/spine.todos",
"pushed_at" : ISODate("2011-11-20T22:59:45Z"),
"searchable_values" : [
"description:a",
"description:backbone",
"description:alternative",
"description:idea",
"html_url:https",
"html_url:github",
"html_url:com",
"html_url:maccman",
"html_url:spine",
"html_url:todos"
],
"tags_array" : [ ],
"watchers" : 139
}
]
}
For the document above, the following find() query would extract both the "nickname" of the document, and its associated "arrangeable_values" (where the document is in the users collection):
db.users.find({}, { "nickname" : 1, "watchlists.arrangeable_values" : 1 })
The result you get for your single document example would be:
{ "_id" : ObjectId("4f6c42f6018a590001000001"), "nickname" : "superj",
"watchlists" : [
{ "arrangeable_values" : { "description" : "My introduction presentation to node.js along with sample code at various stages of building a simple RESTful web service with journey, cradle, winston, optimist, and http-console.", "tag" : "", "html_url" : "https://github.com/indexzero/nodejs-intro" } },
{ "arrangeable_values" : { "description" : "A Backbone alternative idea", "tag" : "", "html_url" : "https://github.com/maccman/spine.todos" } }
] }
MongoDB queries return entire documents. You are looking for a field inside an array inside of the document and this will break the find().
The problem here is that any basic find() query, will return all matching documents. The find() does have the option to only return specific fields. But that will not work with your array of sub-objects. You could returns watchlists, but not watchlist entries that match.
As it stands you have two options:
Write some client-side code that loops through the documents and does the filtering. Remember that the shell is effectively a javascript driver, so you can write code in there.
Use the new aggregation framework. This will have a learning curve, but it can effectively extract the sub-items you're looking for.