Multi ID calls to get() fail with associative array of ids

Apologies if this is the wrong place for this, I couldn’t see how to report an issue via JIRA.

I think there is a bug in the v2 PHP SDK when fetching multiple documents by IDs using an associative array.

I’m using version 2.0.3 of the PHP SDK, and Couchbase version 3.0.2.

Here’s some code demonstrating the problem:

$couch  = new \CouchbaseCluster('couchbase://127.0.0.1');
$bucket = $couch->openBucket('my_bucket', 'my_password');
$ids    = ['foo' => 'doc1', 'bar' => 'doc2'];
print_r($bucket->get($ids));
print_r($bucket->get(array_values($ids)));

The result from the first print_r call is indexed using the keys from my input array, but contains only errors:

...
 [foo] => CouchbaseMetaDoc Object
    (
        [error] => CouchbaseException Object
            (
                [message:protected] => The key does not exist on the server
                ...
        [value] => 
        [flags] => 
        [cas] =>
 [bar] => CouchbaseMetaDoc Object
    (
        [error] => CouchbaseException Object
            (
                [message:protected] => The key does not exist on the server
                ...
        [value] => 
        [flags] => 
        [cas] =>
...

However the second call which converts the array to be numerically indexed results in the expected result:

...
[doc1] => CouchbaseMetaDoc Object
    (
        [error] => 
        [value] => <the document>
        [flags] => 67108864
        [cas] => Resource id #317
    )

[doc2] => CouchbaseMetaDoc Object
    (
        [error] => 
        [value] => <the document>
        [flags] => 67108864
        [cas] => Resource id #318
    )
...

Obviously this is easily worked around, but is probably better addressed in the \CouchbaseBucket class’ get() method.

Performing a multi-get is expected to be performed by using an array of document names. For instance:

$bucket->get(array('document_1', 'document_2', 'document_3'));

The returned array will return an associative array where the array key is the document name, and the array value is the same structure as returned when performing a single operation.

Cheers, Brett

Hi Brett,

I see what you mean about the intended behaviour, but currently you can perform a request exactly as you say and not get back the correct results. I can pass an array of document names, but if that array has non-numeric keys, I do not get back an associative array where the key is the document name, I get back an associative array where the keys correspond to my input array’s keys. Presumably (though I haven’t tested this), if my input array keys happen to be valid document names, I could even get back the wrong results entirely.

I think it would be more useful to either:

  1. Throw an exception if an associative array is passed to get()
  2. Perform the array_values() call inside the extension / do whatever else is required to ignore the array keys.

Personally I think it would be more useful to have the extension convert the input into a useable array since the alternative is that the request fails completely, however if nothing else I think the extension should throw. It’s not obvious from the API or any documentation that the input array must be numerically indexed and it would be quite an easy problem to miss.

Hey Karl,

The SDK actually does support passing values as an associative array for all of its methods. The only issue is that it expects that the array’s keys to correspond to the document key, rather than the value part of the assoc-array. Keep in mind this logic applies to all of our methods to permit you to specify various per-key options when doing mutations and such. Also keep in mind that it is actually considered ‘illegal’ to perform 2 updates to the same key in a single mutation operation (since this doesn’t make any sense anyways).

Cheers, Brett

Thanks Brett, I didn’t realise assoc arrays were specifically supported like that, that’s useful info.

Hi, and apologies if this is not the right place, but I am trying to do a get as explained above and the result is always an array with the keys but null values.
the views are working, the normal get also but when I try to do a get with an array of id’s it doesn’t.

I am using:
couchbase 4.5
php sdk: php_couchbase-2.2.2-7.0-zts-vc14-x86
PHP 7.0.9 (cli) (built: Jul 20 2016 11:08:23) ( ZTS )

Here is a code example :

<?php
$dbconf = new stdClass();
$dbconf->host = 'couchbase://xxx.xxx.xxx.xxx';
$dbconf->user = 'Administrator';
$dbconf->pass =  'foobar';
$dbconf->bucket = 'Audit';

$cluster = new CouchbaseCluster($dbconf->host, $dbconf->user, $dbconf->pass);
$bucket = $cluster->openBucket($dbconf->bucket);

$ids = Array(
	'u:king_arthur' => '',
	'u:king_george' => ''
);

var_dump($bucket->get($ids));

And the result of this is:

array (size=2)
  'u:king_arthur' => null
  'u:king_george' => null

I hope I am doing something wrong, all help will be very appreciate, to be honest I am blocked with this and needs to solve this problem.
Thank you.

could you install libcouchbase2-bin which ships cbc CLI tool or use cbc.exe from libcouchbase package and check these keys using command like this:

cbc cat  -U couchbase://xxx.xxx.xxx.xxx/Audit u:king_arthur u:king_george > /dev/null

And then paste the output here. Also they keys could go just in array("u:king_arthur", "u:king_george")

Could you make sure, you have created those keys through the API, not the Web UI?

Hi Sergey.
Thanks for your response.
the cbc dump is:

CBC: WARNING
  Specifying the default port (8091) has no effect
u:king_arthur        CAS=0xbce9232d7614, Flags=0x2000006. Size=77
{"email":"kingarthur@couchbase.com","interests":["African Swallows","PHP 7"]}
u:king_george        CAS=0x29363f2d7614, Flags=0x0. Size=99
{
  "email": "kingarthur@couchbase.com",
  "interests": [
    "African Swallows",
    "PHP 7"
  ]
}

In this POC the first key was created via a php script and the other using the Web UI, but in my real life problem I have mixed entries restored from a couchbase 2.5 server and these are the entries I must use, I checked some of the entries and some have the CAS and Flags like the first entry of the POC and others not.

Update:
I deleted the entries and recreate again using php sdk, no the cbc dump looks like this:

u:king_arthur CAS=0xbce9232d7614, Flags=0x2000006. Size=77
{“email”:“kingarthur@couchbase.com”,“interests”:[“African Swallows”,“PHP 7”]}
u:king_george CAS=0x9b676e4b7614, Flags=0x2000006. Size=77
{“email”:“kingarthur@couchbase.com”,“interests”:[“African Swallows”,“PHP 7”]}

But still get the same response when trying to query with, change the POC and now looks like this:

$dbconf = new stdClass();
$dbconf->host = ‘couchbase://190.97.163.183:8091?operation_timeout=6000&detailed_errcodes=1’;
$dbconf->user = ‘xxx’;
$dbconf->pass = ‘xxx’;
$dbconf->bucket = ‘Audit’;

$cluster = new CouchbaseCluster($dbconf->host, $dbconf->user, $dbconf->pass);
$bucket = $cluster->openBucket($dbconf->bucket);
$ids = array(“u:king_arthur”, “u:king_george”);

var_dump($bucket->get(“u:king_arthur”));
var_dump($bucket->get(“u:king_george”));
var_dump($bucket->get($ids));

And this is the response:

object(CouchbaseMetaDoc)[6]
public ‘error’ => null
public ‘value’ =>
object(stdClass)[5]
public ‘email’ => string ‘kingarthur@couchbase.com’ (length=24)
public ‘interests’ =>
array (size=2)
0 => string ‘African Swallows’ (length=16)
1 => string ‘PHP 7’ (length=5)
public ‘flags’ => int 33554438
public ‘cas’ => string ‘21mkffj76c’ (length=10)
public ‘token’ => null

object(CouchbaseMetaDoc)[5]
public ‘error’ => null
public ‘value’ =>
object(stdClass)[6]
public ‘email’ => string ‘kingarthur@couchbase.com’ (length=24)
public ‘interests’ =>
array (size=2)
0 => string ‘African Swallows’ (length=16)
1 => string ‘PHP 7’ (length=5)
public ‘flags’ => int 33554438
public ‘cas’ => string ‘1okfx5o7pw’ (length=10)
public ‘token’ => null

array (size=2)
‘u:king_arthur’ => null
’u:king_george’ => null

May I report this as a bug?, How can I do this?
Thanks.

Strange, I’ve just checked the same code, and it works (on your cluster)

when you run your code example in CLI mode, does it work?

When running in CLI mode I got the same response.

Okay. This seems like a bug. I will report it on tracker

Thanks, do you need more details?

System Windows NT WIN7-PC 10.0 build 14393 (Windows 10) i586
Build Date Jul 20 2016 10:44:24
Compiler MSVC14 (Visual C++ 2015)
Architecture x86

extension version 2.2.0
libcouchbase runtime version 2.6.2 (git: 788e1eeda075eddd8204ecc3fc5028add74e8074)
libcouchbase headers version 2.6.1 (git: eb09707433013b742c0aa221e564ad73ba8a3708)

Apache Version Apache/2.4.23 (Win32) OpenSSL/1.0.2h PHP/7.0.9
Apache API Version 20120211

Update: I also tried updating php to version 7.0.11 but the result is exactly the same.

@oscarandreu It seems like we have published broken artifact on our site. the issue is not reproducing when I rebuild extension from the sources, only package on the site affected. Right now I’m continuing investigation what gone wrong. Meanwhile you can download packages from PECL directly: http://pecl.php.net/package/couchbase/2.2.2/windows

Thank you very much!!!

Now is working like a charm :slight_smile: