How to access json value inside reduce function in couchbase? - couchbase

my reduce function in Couchbase[just for testing] :
function(keys,values,reduce){
return values[0];
}
The result is here
{"rows":[
{"key":null,"value":{"doctype":"closed_auctions","buyer":"person14108"}}
]
}
I would like to get individual value inside reduce for further process so when I try to get value of doctype like values[0].doctype it returns null even though there should be "closed_auctions". what is the problem? How can I get individual value(I mean field value) inside reduce function.

Your reduce function called after map performed. Also remember that re-reduce also called and at that time your result is further aggregated. You should use "group=true" when running this view.
So, sometimes values[0] might not have document
You need to check for existence of the property/doc first, e.g.
function(keys, values, rereduce)
{
if (values[0] && values[0].doctype)
{
return values[0].doctype;
}
}
Hope that helps.
See also: 9.5.2.4. Writing Custom Reduce Functions

Related

How can I write a recursion function with a vector parameter?

I have a function that takes a vector as a parameter, scan this vector and generates a random word. It's expected from me that the generated words' letters are different from each other. So, I want to check it with a simple if-else condition inside the same function. If all letters are different, function returns this word. If not, I need to use the same function which I am already inside while using conditions. But first parameter that I used in the main function doesn't work when I attempt to use it for the second time. Here the generateaRandomWord(vector a) function:
vector<string> currentVector;
string generateaRandomWord(vector<string> a) {
currentVector = a;
string randomWord;
int randomNumber = rand() % currentVector.size();
randomWord = currentVector.at(randomNumber);
if (hasUniqueChars(randomWord)) {
return randomWord;
}
else {
generateaRandomWord(currentVector);
}
}
I thought that it is a good idea to keep a vector (currentVector) outside of the function. So, for the first time I use the function this vector will be defined and I will be able to use it if using recursion is necessary. But that didn't work either.
The main problem you have is that your recursive case doesn't return anything -- it throws away the returned value from the recursive call, then falls off the end of the function (returning garbage -- undefined behvaior). You need to actually return the value returned by the recursive call:
return generateaRandomWord(currentVector);

While Iterator in groovy

I'm trying to create a loop to read, for example, 4200 users from 1000 to 1000 but I can't get it to cut when it reaches the end. I tried it with if, for and I couldn't do it.
I have programmed in JAVA but with Groovy I see that the structure is different.
urlUsers = urlUsers.concat("/1/1000");
List<UserConnectorObject> usersList = null;
while({
gesdenResponse = GesdenUtils.sendHttpRequest(urlUsers, "LOOKUP", null,
request.getMetaData()?.getLogin(), request.getMetaData()?.getPassword());
log.info("Users data in JSON: "+gesdenResponse.getOutput())
usersList = GesdenUtils.fromJSON(gesdenResponse.getOutput(), GesdenConstants.USER_IDENTITY_KEY);
usersList.size() == 10;
log.info("List size in JSON "+usersList.size());
}()) continue
Groovy has lots of loop structures, but it is crucial to separate the regular ones (lang built-ins) and the api functions which take closure as an argument
take closure - no plain way to escape
If you want to iterate from A to B users, you can use, for instance,
(10..20).each { userNo -> // Here you will have all 10 iterations
if ( userNo == 5) {
return
}
}
If something outrageous happens in the loop body and you cannot use return to escape, as loop boddy is a closure (separate function) and this resurn just exits this closure. Next iteration will happen just after.
use regular lang built-in loop structures - make use of break/continue
for (int userNo in 1..10) { // Here you will have only 5 iterations
if (userNo == 5) {
break
}
}
It looks like your closure always return falsy because there is no explicit return, and the last statement evaluated is the call to log.info(String) which returns void.
Use an explicit return or move/delete the log statement.

Couchbase rereduce questions

Here is coding from Couchbase Document and I dont understand it
function(key, values, rereduce) {
var result = {total: 0, count: 0};
for(i=0; i < values.length; i++) {
if(rereduce) {
result.total = result.total + values[i].total;
result.count = result.count + values[i].count;
} else {
result.total = sum(values);
result.count = values.length;
}
}
return(result);
}
rereduce means the current function call has already done the reduce or not. right?
the first argument of the reduce function, key, when will it be used? I saw a numbers of examples, key seems to be unused
When does rereduce return true and the array size is more than 1?
Again, When does rereduce return is false and the array size is more than 1?
Rereduce means that the reduce function is called before and now it is called again with params that were returnd as a result in first reduce call. So if we devide it into two functions it will look like:
function reduce(k,v){
// ... doing something with map results
// instead of returning result we must call rereduce function)
rereduce(null, result)
}
function rereduce(k,v){
// do something with first reduce result
}
In most cases rereduce will happen when you have 2 or more servers in cluster or you have a lot of items in your database and the calculation is done on multiple "nodes" of the B*Tree. Example with 2 servers will be easier to understand:
Let's imagine that your map function returned pairs: [key1-1, key2-2, key6-6] from 1st server and [key5-5,key7-7] from 2nd. You'll get 2 reduce function calls with:
reduce([key1,key2,key6],[1,2,6],false) and reduce([key5,key7],[5,7],false). Then if we just return values (do nothing in reduce, just return values), the reduce function will be called with such params: reduce(null, [[1,2,6],[5,7]], true). Here values will be an array of results that came from first reduce calls.
On rereduce key will be null. Values will be an array of values as returned by a previous reduce() function.
Array size depends only on your data. It not depends on rereduce variable. Same answer for 4th question.
You can just try to run examples from Views basics and Views with reduce. I.e. you can modify reduce function to see what it returns on each step:
function reduce(k,v,r){
if (!r){
// let reduce function return only one value:
return 1;
} else {
// and lets see what values have came in "rereduce"
return v;
}
}
I am also confused by the example from the official couchbase website as well, and below is what i thought.
confusion: the reduce method signature
1) its written as
function (keys, values, rereduce)
2) its written as function(key, values, rereduce)
What exactly is the first param, key or keys
For all my understand from my previous exp on the map/reduce, the key the key that emit from the map function and there is a hidden shuffle method that will aggregate the value into a value list for the same key.
So the key param can be an array under the circumstances that you emit an array as key (which you can use group by level control the level of aggregation)
So i am not agree with the example that given by #m03geek, it should not be a list of different keys, correct me if i am wrong.
My assumption:
Both reduce and rereduce work on the SAME key only.
eg:
reduce is like:
1)reduce(keyA, [1,2,3]) this is precalculated, and stored in Btree structure
2) rereduce(keyA, [6, reduce(keyA, [4,5,6])]), 6 is the sum of [1,2,3] from the first reduce method, then we add a new doc into couchbase, which will trigger the reduce method again, instead of calculating the whole thing again as the original map/reduce will do, couchbase get the precalculated data out from the btree which is 6, and run reduce from the key-value pairs from the map method (which is triggered by adding a new doc), then run re-reduce on the precalculated value + new value.

Lua - Execute a Function Stored in a Table

I was able to store functions into a table. But now I have no idea of how to invoke them. The final table will have about 100 calls, so if possible, I'd like to invoke them as if in a foreach loop. Thanks!
Here is how the table was defined:
game_level_hints = game_level_hints or {}
game_level_hints.levels = {}
game_level_hints.levels["level0"] = function()
return
{
[on_scene("scene0")] =
{
talk("hint0"),
talk("hint1"),
talk("hint2")
},
[on_scene("scene1")] =
{
talk("hint0"),
talk("hint1"),
talk("hint2")
}
}
end
Aaand the function definitions:
function on_scene(sceneId)
-- some code
return sceneId
end
function talk(areaId)
-- some code
return areaId
end
EDIT:
I modified the functions so they'll have a little more context. Basically, they return strings now. And what I was hoping to happen is that at then end of invoking the functions, I'll have a table (ideally the levels table) containing all these strings.
Short answer: to call a function (reference) stored in an array, you just add (parameters), as you'd normally do:
local function func(a,b,c) return a,b,c end
local a = {myfunc = func}
print(a.myfunc(3,4,5)) -- prints 3,4,5
In fact, you can simplify this to
local a = {myfunc = function(a,b,c) return a,b,c end}
print(a.myfunc(3,4,5)) -- prints 3,4,5
Long answer: You don't describe what your expected results are, but what you wrote is likely not to do what you expect it to do. Take this fragment:
game_level_hints.levels["level0"] = function()
return
{
[on_scene("scene0")] =
{
talk("hint0"),
}
}
end
[This paragraph no longer applies after the question has been updated] You reference on_scene and talk functions, but you don't "store" those functions in the table (since you explicitly referenced them in your question, I presume the question is about these functions). You actually call these functions and store the values they return (they both return nil), so when this fragment is executed, you get "table index is nil" error as you are trying to store nil using nil as the index.
If you want to call the function you stored in game_level_hints.levels["level0"], you just do game_level_hints.levels["level0"]()
Using what you guys answered and commented, I was able to come up with the following code as a solution:
asd = game_level_hints.levels["level0"]()
Now, asd contains the area strings I need. Although ideally, I intended to be able to access the data like:
asd[1][1]
accessing it like:
asd["scene0"][1]
to retrieve the area data would suffice. I'll just have to work around the keys.
Thanks, guys.
It's not really clear what you're trying to do. Inside your anonymous function, you're returning a table that uses on_scene's return value as keys. But your on_scene doesn't return anything. Same thing for talk.
I'm going to assume that you wanted on_scene and talk to get called when invoking each levels in your game_level_hints table.
If so, this is how you can do it:
local maxlevel = 99
for i = 0, maxlevel do
game_level_hints.levels["level" .. i] = function()
on_scene("scene" .. i)
talk("hint" .. i)
end
end
-- ...
for levelname, levelfunc in pairs(game_level_hints.levels) do
levelfunc()
end

Best way to cache results of method with multiple parameters - Object as key in Dictionary?

At the beginning of a method I want to check if the method is called with these exact parameters before, and if so, return the result that was returned back then.
At first, with one parameter, I used a Dictionary, but now I need to check 3 parameters (a String, an Object and a boolean).
I tried making a custom Object like so:
var cacheKey:Object = { identifier:identifier, type:type, someBoolean:someBoolean };
//if key already exists, return it (not working)
if (resultCache[cacheKey]) return resultCache[cacheKey];
//else: create result ...
//and save it in the cache
resultCache[cacheKey] = result;
But this doesn't work, because the seccond time the function is called, the new cacheKey is not the same object as the first, even though it's properties are the same.
So my question is: is there a datatype that will check the properties of the object used as key for a matching key?
And what else is my best option? Create a cache for the keys as well? :/
Note there are two aspects to the technical solution: equality comparison and indexing.
The Cliff Notes version:
It's easy to do custom equality comparison
In order to perform indexing, you need to know more than whether one object is equal to another -- you need to know which is object is "bigger" than the other.
If all of your properties are primitives you should squash them into a single string and use an Object to keep track of them (NOT a Dictionary).
If you need to compare some of the individual properties for reference equality you're going to have a write a function to determine which set of properties is bigger than the other, and then make your own collection class that uses the output of the comparison function to implement its own a binary search tree based indexing.
If the number of unique sets of arguments is in the several hundreds or less AND you do need reference comparison for your Object argument, just use an Array and the some method to do a naive comparison to all cached keys. Only you know how expensive your actual method is, so it's up to you to decide what lookup cost (which depends on the number of unique arguments provided to the function) is acceptable.
Equality comparison
To address equality comparison it is easy enough to write some code to compare objects for the values of their properties, rather than for reference equality. The following function enforces strict set comparison, so that both objects must contain exactly the same properties (no additional properties on either object allowed) with the same values:
public static propsEqual(obj1:Object, obj2:Object):Boolean {
for(key1:* in obj1) {
if(obj2[key1] === undefined)
return false;
if(obj2[key1] != obj2[key1])
return false;
}
for(key2:* in obj2)
if(obj1[key2] === undefined)
return false;
return true;
}
You could speed it up by eliminating the second for loop with the tradeoff that {A:1, B:2} will be deemed equal to {A:1, B:2, C:'An extra property'}.
Indexing
The problem with this in your case is that you lose the indexing that a Dictionary provides for reference equality or that an Object provides for string keys. You would have to compare each new set of function arguments to the entire list of previously seen arguments, such as using Array.some. I use the field currentArgs and the method to avoid generating a new closure every time.
private var cachedArgs:Array = [];
private var currentArgs:Object;
function yourMethod(stringArg:String, objArg:Object, boolArg:Boolean):* {
currentArgs = { stringArg:stringArg, objArg:objArg, boolArg:boolArg };
var iveSeenThisBefore:Boolean = cachedArgs.some(compareToCurrent);
if(!iveSeenThisBefore)
cachedArgs.push(currentArgs);
}
function compareToCurrent(obj:Object):Boolean {
return someUtil.propsEqual(obj, currentArgs);
}
This means comparison will be O(n) time, where n is the ever increasing number of unique sets of function arguments.
If all the arguments to your function are primitive, see the very similar question In AS3, where do you draw the line between Dictionary and ArrayCollection?. The title doesn't sound very similar but the solution in the accepted answer (yes I wrote it) addresses the exact same techinical issue -- using multiple primitive values as a single compound key. The basic gist in your case would be:
private var cachedArgs:Object = {};
function yourMethod(stringArg:String, objArg:Object, boolArg:Boolean):* {
var argKey:String = stringArg + objArg.toString() + (boolArg ? 'T' : 'F');
if(cachedArgs[argKey] === undefined)
cachedArgs[argKey] = _yourMethod(stringArg, objArg, boolArg);
return cachedArgs[argKey];
}
private function _yourMethod(stringArg:String, objArg:Object, boolArg:Boolean):* {
// Do stuff
return something;
}
If you really need to determine which reference is "bigger" than another (as the Dictionary does internally) you're going to have to wade into some ugly stuff, since Adobe has not yet provided any API to retrieve the "value" / "address" of a reference. The best thing I've found so far is this interesting hack: How can I get an instance's "memory location" in ActionScript?. Without doing a bunch of performance tests I don't know if using this hack to compare references will kill the advantages gained by binary search tree indexnig. Naturally it would depend on the number of keys.