Using Views in couchDB - couchdb

Can you "pass" a "parameter" to a view's map function from the query part of a URL? If so, could you show me an example? By, parameter I mean anyway you can access parts of the query string within the map or reduce function.
Thanks in advance.

That's not quite how views works. The view nominates key-value pairs, where the value could be the whole document. You then ask for something where the key is exactly some value or between a range of values. You have to bend your mind around this way of thinking or it won't make sense. The view is independent of parameters, and then it is narrowed down based on the key or startKey/endKey parameters.

Related

NSFetchRequest that retrieves only the desired attribute of all entities

Is there a way to do a fetch that only returns a list of all the values a specific attribute in a group of entities.
For example, I have a bunch of User entities and they all have an attribute userId. Is there a way to perform a fetch to get all the userIds without having to fetch everything for every user?
I do not know of a way of doing this with a predicate since usually it is used to match attributes that have a specific value (or at least this is how I use it). For example NSPredicate("id = %#),String(a_id)). Which isn't useful for me in this situation. I also tried using something like request.propertiesToFetch = ["id","lastActivityAt"] in an attempt to do this but with two attributes. However this still resulted in me getting every attribute for the students.
Any ideas? I'm doing this in hopes of quicker fetches.
Thanks!
If you're using propertiesToFetch, you also need to use the dictionary result type. That should do you, though it might not make your fetch quicker.

Query to filter by '{Content.Fields.User.XYZ}'

I'm been searching around, and I dont understand why it is, that if I create a query for the projection and I say I want to filter a field of the returned Content Type by a Field of the current user, that no rows are returned.
If I replace the token with a hard coded value, it does work. I'm just missing some important understanding about why the token has no value.
This is not how it works. You may use tokens in projections as long as they are not expected to vary per record. Tokens can be used if they are external data (querystring parameters, etc.) To make your scenario work, you'll have to build your own filter.

Initialize document data source by key attribute (instead of UNID)

We have documents containing "key" of some referenced document. There is reason we don't use UNIDs. I want to initialize data source by this key value. So in Document ID property I write script to open view, look up specified document and use looked up UNID to initialize data source.
I think this is not optimal solution.
Question: is there a better way to initialize document data source based on key value?
Sample code:
#DbLookup("", "view", "key", 1, '[RETURNDOCUMENTUNIQUEID]');
Looking up the document's UNID by key in a view is probably indeed the best way to do it. However, you could speed up repeated calls a bit by writing a managed bean to act as a cache. If, for example, you wrote a Java class that implements java.util.Map, stub out most of the methods, and implement a .get(...) method that takes the key as a parameter, you could reference it like (assuming you call the bean "DocKeyManager"):
<xp:dominoDocument ... documentId="${DocKeyManager[someKey]}"/>
That way, you could cache the value from the .get(...) call and not have to hit the database each time, and it'd also let you change the lookup algorithm later.
You should take a look at Tims article about converting strings to MD2.
this way I think you can convert your string id's to a unid and access them using getDocumentByUnid
http://xmage.gbs.com/blog.nsf/SearchResults?OpenNavigator&Query=md2
We do this a lot, but just remember to do the lookup once (on page load via the $ tag) instead of dynamic (# tag).
If you do it dynamic it will end up doing multiple lookups . . .
The suggestion from Jesse Gallagher to cache lookup results is also a good idea.

CouchDB views - Multiple join... Can it be done?

I have three document types MainCategory, Category, SubCategory... each have a parentid which relates to the id of their parent document.
So I want to set up a view so that I can get a list of SubCategories which sit under the MainCategory (preferably just using a map function)... I haven't found a way to arrange the view so this is possible.
I currently have set up a view which gets the following output -
{"total_rows":16,"offset":0,"rows":[
{"id":"11098","key":["22056",0,"11098"],"value":"MainCat...."},
{"id":"11098","key":["22056",1,"11098"],"value":"Cat...."},
{"id":"33610","key":["22056",2,"null"],"value":"SubCat...."},
{"id":"33989","key":["22056",2,"null"],"value":"SubCat...."},
{"id":"11810","key":["22245",0,"11810"],"value":"MainCat...."},
{"id":"11810","key":["22245",1,"11810"],"value":"Cat...."},
{"id":"33106","key":["22245",2,"null"],"value":"SubCat...."},
{"id":"33321","key":["22245",2,"null"],"value":"SubCat...."},
{"id":"11098","key":["22479",0,"11098"],"value":"MainCat...."},
{"id":"11098","key":["22479",1,"11098"],"value":"Cat...."},
{"id":"11810","key":["22945",0,"11810"],"value":"MainCat...."},
{"id":"11810","key":["22945",1,"11810"],"value":"Cat...."},
{"id":"33123","key":["22945",2,"null"],"value":"SubCat...."},
{"id":"33453","key":["22945",2,"null"],"value":"SubCat...."},
{"id":"33667","key":["22945",2,"null"],"value":"SubCat...."},
{"id":"33987","key":["22945",2,"null"],"value":"SubCat...."}
]}
Which QueryString parameters would I use to get say the rows which have a key that starts with ["22945".... When all I have (at query time) is the id "11810" (at query time I don't have knowledge of the id "22945").
If any of that makes sense.
Thanks
The way you store your categories seems to be suboptimal for the query you try to perform on it.
MongoDB.org has a page on various strategies to implement tree-structures (they should apply to Couch and other doc dbs as well) - you should consider Array of Ancestors, where you always store the full path to your node. This makes updating/moving categories more difficult, but querying is easy and fast.

Why do CouchDB view rows use "key": key, "value":value & not simply key:value

Why does curl http://localhost:5984/blog/_design/comments/_view/total_num?group=true return
{"rows":[
{"key":"sum","value":23},
]}
and not
{"rows":[
{"sum": 23},
]}
There are a couple different reasons.
As Tim McNamara points out, having the key as the member name in the result row means that keys are limited to strings because of the rules of JSON. This way allows people to have view keys of any JSON type.
As Alex Koshelev points out, if we allowed keys as object member names in the view row then the key and value would not be directly addressable. This means that you would have to investigate each and every row to figure out what the key was.
A second aspect of the namespace issue is that a key could conflict with any metadata that may be included in that row. For instance with include_docs=true or the included docid member for non-reduced view output.
Alternatively, if you would like to reformat the output to suit your needs, you can use a _list function to change each row to your liking.
In addition to Alex and Tim's responses:
The view's keys may not be unique, i.e. the same key may have been emitted for multiple documents or even multiple times for a single document.
The view's rows are ordered by key. JSON's object type is an "unordered set of name/value pairs". Many languages, including JavaScript, do not define the order of keys in a mapping. A list is therefore a better representation for something with order.
Allows for null objects as keys.
Each row can have additional data, such as document data (doc) for include_docs=true queries.

Resources