Why doesn't Cloudant / CouchDB compress HTML from the show function? - couchdb

I have a database in Cloudant, and a show function in my design document which generates hefty HTML files:
function(){
return {
body : doc.bunchOfHTML,
headers : {
"Content-Type" : "text/html"
}
}
}
And I've noticed that accessing this page will give back uncompressed HTML. At the same time, when I access my CSS files as attachments of the document, I notice that they are compressed.
Why isn't the output of the show function compressed, and how can we make it so?

It's probably an overlooked / not yet implemented feature.
However, if your documents do not depend on query parameters and are static documents, you could store the HTML as an attachment and use routing to access them. Refer to Cloudant's blog post on the _rewrites array for more information (tip: pay special attention to the 'relative paths' section at the end):
[{
"from": "/mydocs/:docid",
"to": "/../../:docid/show.html",
"query": {}
}]
Drawback to this method is that your 404s will be ugly, unless you have so little documents that you can route them individually.

Related

Should REST api PUT accept a request with a single edited property and the id of the document?

Or should the client send every time every property even if they were not edited?
So imagine on the server I have stored in my DB the following document:
{
_id: "1",
name: "Mario",
surname: "Rossi"
}
Now imagine the client wants to update JUST the name. Should this PUT request be acceptable?
{
_id: "1",
name: "Giorgio"
}
Or should the client send all properties?
{
_id: "1",
name: "Giorgio",
surname: "Rossi"
}
It seems like partial edits can save some bandwidth and it does not really make sense to send extra data, but I'm not sure about what's the standard here.
Thanks!
The representation you send with a PUT request should be the same that you expect to get back from a GET request.
A successful PUT of a given representation would suggest that a subsequent GET on that same target resource will result in an equivalent representation being sent in a 200 (OK) response. -- RFC 7231
In other words, the representation included in the body of a PUT request is expected to be the complete representation.
See also the introduction for HTTP Patch:
The existing HTTP PUT method only allows a complete replacement of a document.
Roy Fielding, writing in 2012:
When a server that implemented PUT prior to the introduction of Content-Range received a partial content body that included such a range, they would replace the entire resource representation with the partial body. That is how PUT was defined to work.... the introduction of partial PUT would only be possible with a strong coupling between client and origin server implementations, which violates the design of the HTTP.
There are cases where the representation is very large (much larger than the HTTP headers), and the changes we are making are small, where it would be sensible to send a representation of the changes, rather than the complete representation.
But PUT isn't the method we use in that case, because the semantics are wrong. Our standards compliant choices here are to end the entire (revised) representation with PUT, or a representation of the changes in a patch-document with PATCH.

can array of links be fetched / resolved in an Entry request

I am requesting a specific Entry and one of the fields of that Entry is an array of links. Is there a way to get those links to be resolved and returned in the resulting JSON response?
I am trying this via curl
curl -v https://cdn.contentful.com/spaces/o2bhdl4js7ak/entries/<entryID>?access_token=<accessToken>&include=2
The "include=n" parameter does not work in this particular case. should it?
Here's a snippet with the field I expect to be resolved / expanded
"lessons": [
{
"sys": {
"type": "Link",
"linkType": "Entry",
"id": "26hzvgmWtqOcKeoeMQOAoO"
}
}
],
Have another read of the Links page on Contentful Developer Documents.
Contentful Developer Documents - Links
to get a relationship link into the json you are requesting then you change the request link slightly as documented. instead of using the entryID where you have it after the entries/ in your link in the question, use it as demonstrated below.
https://cdn.contentful.com/spaces/oc3u7dt7mty5/entries?access_token=6cabb22c95d52aa7752fe70ae9b3271a1fc2decf7ae7d99ccd7dceba718980e6&content_type=3HjHXUYR3yyosUqAGmi8wu&fields.restaurantField.sys.id=2UmoQ8Bo4g4S82WmGiQIQE
It's been moved into the sys.id at the end of the URL.

CouchDB view default options in design document not working

The problem is simple: I have written map functions in a design document of a CouchDB database, which emits something {"_id":doc._id}. Together with include_docs=true query option, I will get the desired results with the linked documents. Because the map functions are designed to work with include_docs=true, I put this option in the design document and make it default:
{...
"options":{"include_docs":true}
...}
However, when I query the view, the results are still those without the linked documents, and I need to specify the option explicitly in the query. I also tried to pu other query option (e.g. limit=200) into the design document, they did not work either.
I am using CouchDB 1.5, and cannot find any discussion, issue or bug regarding this. Does anyone have any idea? Thanks in advanced!
Edit: I have reported the issue in Apache, and I am told that the statement about this was removed.
_design/ddoc/options cannot do that.
According to couchdb's docs, a design doc's options object properties only affect view indexing, not view querying. (The only two settings being local_seq and include_design).
_design/ddoc/rewrites can!
If you want to set query options server side, you can do so by specifying a rewrites array in your design document.
Let's say you want to expose a query to _view/myview that has include_docs set to true, you add the following rewrites array to your design document:
{ "_id": "_design/myddoc"
, "views": { "myview": { "map": "function(doc) { ... }" } }
, "rewrites":
[ { "from": "allmyviews/myview"
, "to": "_view/myview"
, "query":
{ "include_docs": "true"
}
}
]
}
Now, when you request http://localhost:5984/mydb/_design/myddoc/_rewrite/allmyviews/myview without the include_docs parameter, couchdb will respond as if you had included it.

CouchDB: Struggling with concept to get data displayed in a web page

As previously advised I have set up a database on iriscouch. Entered a couple of records.
I read in the CouchDB Guide book, I need to create a map function, in order to see my records
eg
function(doc) {
if(doc.date && doc.title) {
emit(doc.date, doc.title);
}
}
Now where do I put this function. Is it a MySQL like view and saved in the database and how do I get the result to my web page ?
Do I create the view within iriscouch somehow ?
Any guidance gratefully received as it is the usual first tentative steps problem of just not getting the idea and I have yet to find a 'Hello World' example which shows all steps.
Thanks
mcl
To me, it is similar as files on a computer filesystem. Most files just store data. But some files are also programs which can run and become an application. In CouchDB, all data is stored in documents however some documents activate special behavior in CouchDB. These are called design documents.
Design documents have an id of _design/example, i.e. it must start with _design/. You can create a document with the Futon tool, just like any other document. Add a key called views with a value of a JSON object:
{ "titles_by_date":
{ "map": "function(doc) { if(doc.date && doc.title) emit(doc.date, doc.title); }"
}
}
If you have other questions, there is also the Iris Couch forum any discussion about CouchDB and Iris Couch.

CouchDB - Parameter and views - What goes on behind the scenes, and is it fast/faster than temporary views?

Considering these three documents...
[
{
_id: "...",
_rev: "...",
title: "Foo",
body: "..."
},
{
_id: "...",
_rev: "...",
title: "Bar",
body: "..."
},
{
_id: "...",
_rev: "...",
title: "Hello World!",
body: "..."
},
]
And this view...
byTitle: {
map: function (document)
{
emit(document.title, document);
}
}
What goes on behind the scenes, when I query the view?...
GET /database/_design/posts/_view/byTitle?key="Foo"
I've asked a few questions on views lately... questions about what I phrased as "dynamic parameters"... Essentially I wanted to know how to do the equivalent of SELECT ... WHERE field = parameter
All answers steered me towards using temporary views, which are really slow, and should not be used in production. So my second question is... is the above method for querying by title, fit for use in production? Or am I forcing CouchDB to do unspeakable horrors, performance-wise?... am I essentially doing the same as using a temporary view?
I think you have misinterpreted some answer. You can use a temporary view to test various map/reduce functions. When you are satisfied with the code you should put it into a design document and use it for querying.
Temporary views are slow because the index is built and deleted for every query. Putting it into a design document, tells CouchDB to not delete the index and to keep it updated (this is done on query time).
So
GET /database/_design/posts/_view/byTitle?key="Foo"
is the fastest way to query by title because it is indexed.
As a side note: you can use
byTitle: {
map: function (document)
{
emit(document.title, null);
}
}
and query with include_docs=true to save some disk space.
For answering your question, a few things have to be cleared out (and I hope I get it all right):
Permanent vs. temporary views:
The difference between permanent and temporary views is, that permanent views are stored permanently.
In order to understand the storing part, you need to know, that CouchDB's storage engine relies on a B+ Tree offering very powerful indexing capabilities that enable us to find data in that storage by key in a "logarithmic amortized time" (CouchDB book).
CouchDB is handling documents in an "append only" manner. That means it is not like in the most relational DBMS where single values within a table row get updated and locking occurs. If a document is updated, it simply incrementally is set a new revision (_rev) and is appended to the storage.
When you are creating a permanent view, upon querying it the first time, for each document in your database, your new view is executed, storing that data to a new B+ tree file for that view, thus providing a new index to aggregate data according to the key you defined in your view.
Upon updating documents that are handled by that view, not the whole permanent view needs to be recomputed, but only the updated documents.
Now you should be able to understand why temporary views are nice for developing or testing in Futon, but since they have to be computed new for all your documents are not recommended for anything else than development.
Anyways. Marcello is right. If you are intending to just pass back complete documents, it is are encouraged to query with "include_docs=true". Why? Because the B-tree for your permanent view will just need to store the copied data next to your indexing key.
#Marcello-Nuccio I am not sure although if it is correct to say, that dynamic views have no index? As I understood, they have an index, but it makes no sense as they are computed new upon every query? Ok, now my brbain is hurting!

Resources