CouchDB - view recursivity - couchdb

I have a question about querying CouchDB.
I have a query that generates a set of outputs. These outputs are also the result of another query.
I want to define a CouchDB view permitting to get all the outputs (and the inputs of a specific document). Is it possible to get the results of a map function and consider them as un input of another map function ?
In SPARQL, I have do this query, it is modeled as follow :
SELECT ?linkedAction
WHERE { ?action nova:hasOutput ``doc-02-10-C''.
?action (nova:hasInput/^nova:hasOutput)* ?linkedAction.
}
Is it possible to do that in map/reduce ?
Best Regards.
Amin

You can try Couch-Incarnate.
Or use Cloudant chained mapreduce views (hopefully it will be integrated in CouchDB).

No, each view index is completely isolated from other views. (and other databases for that matter) CouchDB's incremental view updates would be impossible to keep efficient when changes from one view can affect another. You'll need to perform this kind of additional processing in your application layer.

Related

Filter a subset of fields when replicating in couchdb

I have some documents I would like to replicate to per user databases but only with a subset of fields on the main document. The "selector" option works great to easily select the docs I need but it does not appear to support the "fields" option. I can't find a way to do this without manually filtering the document fields on my node server, which seems quite inefficient.
It is not possible to replicate part of a document. The CouchDB replication mechanism is replicating the whole document as a unit.
I suggest you to review your document design in order to have a better fit with the replication requirements. Maybe it is more accurate to have two separate documents in your case.

Can CouchDB do this?

I evaluating CouchDB & I'm wondering whether it's possible to achieve the following functionality.
I'm planning to develop a web application and the app should allow a 'parent' table and derivatives of this table. The parent table will contains all the fields (master table) and the user will selectively choose fields, which should be saved as separate tables.
My queries are as follows:
Is it possible to save different versions of the same table using CouchDB?
Is there an alternative to creating child tables (and clutter the database)?
I'm new to NoSQL databases and am evaluating CouchDB because it supports JSON out of the box and this format seems to fit the application very well.
If there are alternatives to NOT save the derivatives as separate tables, the better will the application be. Any ideas how I could achieve this?
Thanks in advance.
CouchDB is a document oriented database which means you cannot talk in terms of tables. There are only documents. The _rev (or revision ID) describes a version of a document.
In CouchDB, there are 2 ways to achieve relationships.
Use separate documents
Use an embedded array
If you do not prefer to clutter your database, you can choose to use option (2) by using an embedded array.
This gives you the ability to have cascade delete functionality as well for free.

Cloudant: Indexes vs Views

Are Cloudant's concept of Indexes native to CouchDB? It appears the Cloudant has built their Index feature on top of CouchDB, is this correct? If so, what is the difference between an Index and a View?
The Query interface is (currently) a simplifying API for creating and accessing the undelying CouchDB views. The indexes you define via the _index endpoint are actually translated into views, and those views can be accessed and used in the same way as a normal CouchDB view, as well as via the _find endpoint (note: the inverse is not true - Query doesn't currently use existing javascript views). The views stay in the erlang layer so gives us the opportunity for performance enhancements etc.
You can also filter result data to only return document fields you're interested in, as opposed to hard coding the returned fields in the view or running the view result through a list function.
Cheers
Simon

CouchDB, how to get document changes only

Using /_changes?filter=_design I can get all the changes for design documents.
How do I get all the changes for documents only?
Is there such a thing like /_changes?filter=_docs_only ???
There is no built in filter for this. You will need to write your own filter function (http://couchdb.readthedocs.org/en/latest/couchapp/ddocs.html#filterfun) that excludes design documents (check the doc's _id for "_design/", etc.) from the feed. You then reference this filter function when you query the changes feed (http://couchdb.readthedocs.org/en/latest/api/database/changes.html?highlight=changes). However, most applications don't run into this too often since design documents are typically only updated when there is an application change.
It would probably be more efficient to implement this filter on the client side instead of streaming all your changes to the couchjs process (always inefficient). As your application loops through the changes simply check whether it is a design doc there.
Cheers.

CouchDB map/reduce by any document property at runtime?

I come from a SQL world where lookups are done by several object properties (published = TRUE or user_id = X) and there are no joins anywhere (because of the 1:1 cache layer). It seems that a document database would be a good fit for my data.
I am trying to figure-out if there is a way to pass one (or more) object properties to a CouchDB map/reduce function to find matching documents in a database without creating dozens of views for each document type.
Is it possible to pass the desired document property key(s) to match at run-time to CouchDB and have it return the objects that match (or the count of object that match for pagination)?
For example, on one page I want all posts with a doc.user_id of X that are doc.published. On another page I might want all documents with doc.tags[] with the tag "sport".
You could build a view that iterates over the keys in the document, and emits a key of [propertyName, propertyValue] - that way you're building a single index with EVERYTHING prop/value in it. Would be massive, no idea how performance would be to build, and disk usage (probably bad).
Map function would look something like:
// note - totally untested, my CouchDB fu is rusty
function(doc) {
for(prop in doc) {
emit([prop, doc[prop]], null);
}
}
Works for the basic case of simple properties, and can be extended to be smart about arrays, and emit a prop/value pair for each item in the array. That would let you handle the tags.
To query on it, set [prop] as your query key on the view.
Basically, no.
The key difference between something like Couch and a SQL DB is that the only way to query in CouchDB is essentially through the views/indexes. Indexes in SQL are optional. They exist (mostly) to boost performance. For example, if you have a small DB, your app will run just fine on SQL with 0 indexes. (Might be some issue with unique constraints, but that's a detail.)
The overall point being is that part of the query processor in a SQL database includes other methods of data access beyond simply indexes, notably table scans, merge joins, etc.
Couch has no query processor. It has views (defined by JS) used to define B-Tree indexes.
And, that's it. That's the hammer of Couch. It's a good hammer. It's been lasting the data processing world for basically 40 years.
Indexes are somewhat expensive to create in Couch (based on data volume) which is why "temporary views" are frowned upon. And they have a cost in maintenance as well, so views need to be a conscious design element in your database. At the same time, they're a bit more powerful than normal SQL indexes as well.
You can readily add your own query processing on top of Couch, but that will be more work for you. You can create a few select views, on your most popular or selective criteria, and then filter the resulting documents by other criteria in your own code. Yes, you have to do it, so you have to question whether the effort involved is worth more than whatever benefits you feel Couch is offering your (HTTP API, replication, safe, always consistent datastore, etc.) over a SQL solution.
I ran into a similar issue like this, and built a quick workaround using CouchDB-Python (which is a great library). It's not a pretty solution (goes against the principles of CouchDB), but it works.
CouchDB-Python gives you the function "Query", which allows you to "execute an ad-hoc temporary view against the database". You can read about it here
What I have is that I store the javascript function as a string in python, and the concatenate it with variable names that I define in Python.
In some_function.py
variable = value
# Map function (in javascript)
map_fn = """function(doc) {
<javascript code>
var survey_match = """ + variable + """;
<javascript code>
"""
# Iterates through rows
for row in db.query(map_fn):
<python code>
It sure isn't pretty, and probably breaks a bunch of CouchDB philosophies, but it works.
D

Resources