How can I guarantee that a view returns the last inserted value also

Steps:

  1. Write a key/value using ExecuteStore command
  2. I immediately try to get the last inserted value like this:
    var view = _instance.GetView(“all_docs”, “all_docs”);
    view = view.Stale(StaleMode.False);
    var documents = view.Select(GenerateCacheData);
    _iterator = documents.GetEnumerator();

The problem is that the view is not yet updated/indexed with the new value.

I have already read this: http://www.couchbase.com/forums/thread/stalefalse-supported
So, how can i be sure that I get the list of all inserted elements in the order of insertion including the last inserted one ?

Also take in consideration that i am forced to use views because of other reasons. One of the reason is that at the second step I don’t know the name of the key that i inserted at the first step.

However, the bottom line is that I want to take inserted keys in the order of insertion but to be sure that i take the last inserted one also. What else can I use if not views ?

Thank you for your effort,
Andrei Nechifor

I also tried:

_instance.ExecuteStore(StoreMode.Set, json.GetValue("_id").ToString(), json.ToString(), PersistTo.One, ReplicateTo.Zero); But then i received:

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
at Couchbase.ObserveHandler.<>c__DisplayClass9.b__4(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.TimerQueueTimer.CallCallback()
at System.Threading.TimerQueueTimer.Fire()
at System.Threading.TimerQueue.FireNextTimers()

That code should work assuming you have two or more nodes in your cluster. You definitely shouldn’t be getting a NRE.

For example:

using (var client = new CouchbaseClient(“default”, “”))
{
var json = “{“name”:“blah”, “_id”:“id1”}”;
var result =client.ExecuteStore(StoreMode.Set,
“id1”,
json, PersistTo.One,
ReplicateTo.Zero);

            Assert.IsTrue(result.Success);
        }

That code works as expected running against a four node VM cluster on my development machine.

-Jeff

That is good to know. Indeed i only have one node.

However, can you please help me with the main question ?

Thank you,
Andrei Nechifor

Andrei -

Your options are using observe (and block the view call until the durability requirements are met) or perhaps using a meta-doc to store a set of keys. The meta-doc concept, should give you what you need, you’ll just have to do some data modeling to ensure it fits your use case.

Personally, I would use the meta-doc. It supports your requirements for “get the list of all inserted elements in the order of insertion including the last inserted one” and you won’t have to know the key you inserted in the first step, it will be: it’s simply the last key in the list stored under a shared “primary” key. Also, being K/V based it will have better performance than using views.

-Jeff

First I want to thank you for the answer and trying to help me in this situation

Solution 1: use observe.
Is not very good because it can block my write operation for a long time to wait for the view to update. But my application uses write operations all the time. And there is no possibility to force the view to update.

Solution 2: meta-doc
The problem is that at least 2 clients will work in parallel having 2 distinct instances of my application so the main memory is not going to be shared between them. And I need the last descriptions at the level of the database.

So we need something like “select * from database” without using views

I am starting to think that Couchbase is simple not optimized for this kind of scenario. It works perfect for other scenarios.

Thank you,
Andrei Nechifor

Andrei -

For solution 2, you can CAS (Check and Set) to manage optimistic concurrency. The key just needs to be shared - you could do this via configuration.

You can read more about CAS here:

  • http://docs.couchbase.com/couchbase-devguide-2.0/#check-and-set-cas
  • http://docs.couchbase.com/couchbase-sdk-net-1.3/#cas-methods

As for select * from database, we do have a SQL-like language in development called N1QL: http://www.couchbase.com/communities/n1ql

However, it’s still in DP and not production ready as of 8/7/2014.

-Jeff