What is the right way to create and use a view on touchdb + ektorp combination?

122 views
Skip to first unread message

Gaara

unread,
May 25, 2012, 1:56:35 AM5/25/12
to mobile-c...@googlegroups.com
I've been looking through the GrocerySync example that uses touchdb and ektorp and saw how the view was created. On the other hand, i was going through the Ektorp documents and found different information on view creation. I was wondering whether it would still be applicable if i had to create a view on android.

1.Do i have to use any of these things? 

TDView view = db.getViewNamed(String.format("%s/%s", dDocName, byDateViewName));
   view.setMapReduceBlocks(new TDViewMapBlock() {

            @Override
            public void map(Map<String, Object> document, TDViewMapEmitBlock emitter) {
                Object createdAt = document.get("created_at");
                if(createdAt != null) {
                    emitter.emit(createdAt.toString(), document);
                }

            }
        }, null, "1.0");

Couple of questions related to this is,
Does this view get created permanently on touchdb? If not, how do i make it exist permanently (under the assumption if it is permanent that the next time it is referred, everything will be faster) 

If this is not the right way to do it, is this the correct way to do it?

Create a class which extends CouchdbDocument called X.
Then create a class which extends Couchdbrepositorysupport<x> and register a view in that.

Thanks in advance

Marty Schoch

unread,
May 25, 2012, 8:26:18 AM5/25/12
to mobile-c...@googlegroups.com
Hello,

These are great questions. The implementation of views in the core of
TouchDB relies on native code for that platform. This means that they
are provided to the TouchDB Server at runtime and give a name and
version number. This is in contrast to CouchDB where they are written
in javascript and stored in design documents. One important thing to
note though is that in both cases, the result of the view (the index
that is built) is stored. This means that if you don't change the
definition of your view (signaled to the server through the name and
version) it need not be recreated, even between application restarts.

Also, indirectly related to your question I should mention we have a
Javascript module which adds the capability to run Javascript
map/reduce views. However, this will add about 1MB to your
application.

I'll address the specific questions you have inline below:

On Fri, May 25, 2012 at 1:56 AM, Gaara <aka...@gmail.com> wrote:
> I've been looking through the GrocerySync example that uses touchdb and
> ektorp and saw how the view was created. On the other hand, i was going
> through the Ektorp documents and found different information on view
> creation. I was wondering whether it would still be applicable if i had to
> create a view on android.
>
> 1.Do i have to use any of these things?
>
> http://www.ektorp.org/javadoc/ektorp/1.2.2/org/ektorp/support/CouchDbRepositorySupport.html
> http://www.ektorp.org/javadoc/ektorp/1.2.2/org/ektorp/ViewQuery.html
> http://www.ektorp.org/reference_documentation.html#d100e740

CouchDbRepositorySupport - You can use a subset of this functionality.
(I haven't used it, but we have some successful reports of it
working) The subset of functionality that does not work yet revolves
around the designDocumentFacotry. This is what Ektorp uses to
automatically generate map/reduce views to access the data. We'd like
to add support for this in the future. Here is a related issue we're
tracking https://github.com/couchbaselabs/TouchDB-Android/issues/17

ViewQuery is still used. GrocerySync has an example of how to use it.
The key thing here is that you have to register your view first using
a name that simulates a design document name. So in GrocerySync we
name the view "grocery-local/byDate". Then when we access the view we
use:

new ViewQuery().designDocId("grocery-local").viewName("byDate").descending(true)

The @Views annotation which allows you to define views with in-line
javascript is not supported at this time.

> 2. Or do i have to use TDView class to create and interact with a view? As
> taken from the GrocerySync example.
>
> TDView view = db.getViewNamed(String.format("%s/%s", dDocName,
> byDateViewName));
>    view.setMapReduceBlocks(new TDViewMapBlock() {
>
>             @Override
>             public void map(Map<String, Object> document, TDViewMapEmitBlock
> emitter) {
>                 Object createdAt = document.get("created_at");
>                 if(createdAt != null) {
>                     emitter.emit(createdAt.toString(), document);
>                 }
>
>             }
>         }, null, "1.0");

Yes this is the correct way to register a view in TouchDB-Android.

> Couple of questions related to this is,
> Does this view get created permanently on touchdb?

The results of the map function are persisted. The name and version
number of the view are used to let TouchDB know when it can use the
values its already calculated, and when it has to regenerate the
values.

> If not, how do i make it
> exist permanently (under the assumption if it is permanent that the next
> time it is referred, everything will be faster)

The only thing you need to do is pass the same name and version and
the values will be reused. If you change the definition of the view,
you should bump the version number.

> If this is not the right way to do it, is this the correct way to do it?
>
> Create a class which extends CouchdbDocument called X.
> Then create a class which extends Couchdbrepositorysupport<x> and register a
> view in that.
>
> Thanks in advance

Hopefully things are a bit more clear now. I've tried to update the
wiki with some of these questions, please take a look and feel free to
contribute other improvements there.

https://github.com/couchbaselabs/TouchDB-Android/wiki

marty

Akash

unread,
May 25, 2012, 10:40:16 AM5/25/12
to mobile-c...@googlegroups.com

Thank you for your reply.

Based on your replies I have some more doubts which I'd like to get clarified. (Please excuse me if questions are not too detailed, I'm typing for my phone)

1. You have said that on creating/registering a view during run time,it will actually store the results of the view so that it can be retrieved later by using viewquery. Does this mean the map logic is stored or only the results are stored? If its the former, then retrieving the view should give me results which will vary, if its the latter, I'm guessing it acts much like a cached version of the view, which is much unlike how the views work in any couchdb. I'm guessing it is the former.

In the case that it is the former, how does one detect the change in the view, especially if I've attached a listviewadapter to the view results?

2. Does the tdview object have to live as long as the activity lives, or is it ok to put it in local scope of a function and let it die, because you have said that a view's design document will get registered anyways.

Thanks

Marty Schoch

unread,
May 25, 2012, 10:53:43 AM5/25/12
to mobile-c...@googlegroups.com
On Fri, May 25, 2012 at 10:40 AM, Akash <aka...@gmail.com> wrote:
> Thank you for your reply.
>
> Based on your replies I have some more doubts which I'd like to get
> clarified. (Please excuse me if questions are not too detailed, I'm typing
> for my phone)
>
> 1. You have said that on creating/registering a view during run time,it will
> actually store the results of the view so that it can be retrieved later by
> using viewquery. Does this mean the map logic is stored or only the results
> are stored?

The map logic is NOT stored. You must register the logic each time
your application is run.

The results of the map function ARE stored. It is expected that your
application registers the same map/reduction functions with the same
name and version on each launch. If you decide to change your logic,
you should bump the version number. This way TouchDB knows to
invalidate all the previously generated map results, and recreate the
index.

> If its the former, then retrieving the view should give me
> results which will vary, if its the latter, I'm guessing it acts much like a
> cached version of the view, which is much unlike how the views work in any
> couchdb. I'm guessing it is the former.

I'm not sure I follow you here. If your map logic changes, you need
to bump the version number so that TouchDB will know to invalidate the
previous map results and rebuild the index. If your logic does not
change, it does not need to re-run the map function for documents that
were already indexed.

It works very much like CouchDB. Once you run the map function for a
particular revision of a document you do not need to run it again,
unless either the document changes or the design document changes.
This operates the same way.

> In the case that it is the former, how does one detect the change in the
> view, especially if I've attached a listviewadapter to the view results?

I don't believe CouchDB offers any specific functionality to know that
a view changes. Typically you follow the _changes feed, possibly with
a filter and use that to know when changes that may have changed the
view take place. We use the same approach in GrocerySync. If you
take a look at the CouchbaseViewListAdapater, it has a flag to follow
the changes feed. It's not very intelligent, it doesn't use any
filter. It just follows the changes feed, and if anything changes, it
triggers an update.

> 2. Does the tdview object have to live as long as the activity lives, or is
> it ok to put it in local scope of a function and let it die, because you
> have said that a view's design document will get registered anyways.

Once you register the view TouchDB will keep a reference to this
object. So it will not get garbage-collected until TouchDB itself is
shutdown.

marty
Reply all
Reply to author
Forward
0 new messages