Couchbase 7.0.2 nodejs v3 viewQuery key field

Hi, we are trying Couchbase “couchbase”: “3.2.5” with couchbase v7 and TypeScript.
We got some problem with key query.

with sample bucket gamesim-sample, I have create a new VIEW

function (doc, meta) {
  if (doc.jsonType == "player" && doc.loggedIn != null) {
  emit([doc.loggedIn, doc.name], null);
  }
}

then try with nodejs.
method A: with nodejs, I can get the correct search result

var bucket = cluster.bucket('gamesim-sample')
  const viewResult = await bucket.viewQuery(
    "players_update",
    "playerlist",
    { 
        timeout:10000,
        stale: "false",
        // keys: [[true, "Aaron0"]] // ok
        key: Array.from([true, "Aaron0"]) // ok
    }
  ).catch((e)=>{console.log(e); throw e;});
  viewResult.rows.forEach((row)=>{
     console.log(row);
  });
ViewRow { value: null, key: [ true, 'Aaron0' ], id: 'Aaron0' }

method B: switch the same code to TypeScript. I will get a type assignment error

Type '(string | boolean)[]' is not assignable to type 'string'.ts(2322)

is it a bug or any other workaround to resolve this issue? also for keys query.

in the type definition viewtypes.d.ts , I can see the type is declared as a string

export interface ViewQueryOptions {
    /**
     * Specifies a specific key which should be fetched from the index.
     */
    key?: string;
    /**
     * Specifies a list of keys which should be fetched from the index.
     */
    keys?: string[];
}

Hey @ddc,

I don’t have easy access to TypeScript at the moment, but it seems it’s just a type error, since the array of values is not converted to string. Have you tried converting the JSON object(s) to String, using something like JSON.stringify([true, 'Aaron0')?

thanks, @Nebasuke I also try with

key: JSON.stringify([true, "Aaron0"]) // nothing

no output, also debug several other ways, only pass an array works.
which currently, totally blocks any TypeScript integration.

try with another way.

// Open a bucket to allow cluster-level querying
  var bucket = cluster.bucket('gamesim-sample')
  const viewResult = await bucket.viewQuery(
    "players_update",
    "playerlist",
    { 
        timeout:10000,
        stale: "false",
        key: JSON.stringify([true, "Aaron0"]) // JSON.stringfy in my business code, and pass string as the type definition in `viewtypes.d.ts`
    }
  ).catch((e)=>{console.log(e); throw e;});
  viewResult.rows.forEach((row)=>{
     console.log(row);
  });

and go to the /node_modules/couchbase/dist/viewexecutor.js L67
debug with below ways

  1. with the original JSON.stringfy, actually, key is stringfy twice, and no output
  2. remove the original JSON.stringfy, match the type definition and only stringfy once. and I can see the output
if (options.key !== undefined) {
      // try 1
      // original in the couchbase SDK, doesn't work
      queryOpts.key = JSON.stringify(options.key); 

      // try 2
      // remove the JSON.stringfy function, and works
      queryOpts.key = options.key; 
 }

and should same for keys field, I think should be a bug to this SDK from the beginning.

@Nebasuke

After trying to debug the code, I find below changes works for me.

  1. in the node_modules/couchbase/dist/viewtypes.d.ts L213, keep the key definition as string
/**
* Specifies a specific key which should be fetched from the index.
*/
key?: string;
  1. in the node_modules/couchbase/dist/viewexecutor.js L67, remove the JSON.stringfy operation, update as below
if (options.key !== undefined) {
    //queryOpts.key = JSON.stringify(options.key);
    queryOpts.key = options.key;
}

with above changes, it works for me, same for keys field, I think it should be a bug, JSON.stringfy twice for the same key for key.

I have created a PR for this issue.

1 Like

Thanks for the PR - I’ll talk with the SDK team about this.

-Aaron