Problem with query from PHP script


#1

We were initially using:
/$couchResult = json_decode(json_encode($couchBucket->query($couchQuery)), true);
but I was advised that as this is encoding and then decoding it uses more resources. @srm gave me a tip on how to optimise this by using:
$couchResult = $couchBucket->query(\CouchbaseN1qlQuery::fromString($couchQuery), true);

However, I am receiving this PHP error.

An exception occurred: LCB_EINVAL: Invalid input/arguments in [CouchbaseNative]/CouchbaseBucket.class.php on line 316

_CouchbaseBucket->n1ql_request() in [CouchbaseNative]/CouchbaseBucket.class.php at line 316
CouchbaseBucket->_n1ql() in [CouchbaseNative]/CouchbaseBucket.class.php at line 378
CouchbaseBucket->query() in /var/www/exfusion.net/html/unlink.php at line 48

Does anybody know what I am doing wrong?


#2

Can you paste the content of $couchQuery please.
Try your query in the interface : http://localhost:8091/ui/index.html#/query/workbench


#3

And version of the extension


#4
$couchCluster = new CouchbaseCluster('couchbase://datastore.exfusion.net');
$couchBucket = $couchCluster->openBucket('OUR_BUCKET', 'OUR_PASSWORD');
$couchQuery = CouchbaseViewQuery::from("playerdata", "by_name")->key(strtolower($mcuser));
$couchResult = $couchBucket->query(\CouchbaseN1qlQuery::fromString($couchQuery), true);
couchbase support	enabled
extension version	2.2.0
libcouchbase runtime version	2.6.2 (git: 788e1eeda075eddd8204ecc3fc5028add74e8074)
libcouchbase headers version	2.6.2 (git: 788e1eeda075eddd8204ecc3fc5028add74e8074)

#5

You can’t use this like that.
You should use a N1QL query not a view, i’ll search in the API if you can use view and decode json as array.


#6

Okay, thanks. Sorry - I’m new to Couchbase and don’t have a particularly strong knowledge of PHP.


#7
$couchCluster = new CouchbaseCluster('couchbase://datastore.exfusion.net');
$couchBucket = $couchCluster->openBucket('OUR_BUCKET', 'OUR_PASSWORD');
$couchQuery = CouchbaseViewQuery::from("playerdata", "by_name")->key(strtolower($mcuser));
$couchResult = $couchBucket->query($couchQuery, true);

Should work.


#8

you have to decide what do you need View or N1QL query. So either:

$couchQuery = CouchbaseViewQuery::from("playerdata", "by_name")->key(strtolower($mcuser));
$couchBucket->query($couchQuery, true);

or

$couchQuery = CouchbaseN1qlQuery::fromString("SELECT * FROM `OUR_BUCKET`");
$couchBucket->query($couchQuery, true);

#9

Ooh, thanks to both of you! I’ve got it working again. I didn’t realise that CouchBucket query accepted a second parameter to return it as an array. (is it just me who finds that the official documentation is difficult to find???)


#10

No i think the same thing about documentation.
So i always read the source :


#11

#Bookmarked. Cheers.


#12

Sorry but what do I do here to fetch as an array?
try { $couchResult = $couchBucket->get("playerdata:" . $fields["mcuuid"]); } catch (Exception $ex) { return false; }


#13

You can’t.
get always return raw document.
So you need to use json_decode if you have a json :slight_smile:


#14

Any way to get it as JSON string rather than an annoying Couchbase Document Object??


#15

What wrong with document object? Why string is easier to manipulate? To access fields you still need to parse JSON anyway.


#16

Sorry not what I meant to ask. I meant to ask: how do I take a Couchbase get request and put those values into a PHP array?


#17

Default serializer gives you stdClass which could be represented as PHP array easily:

<?php
$cluster = new CouchbaseCluster("couchbase://localhost");
$bucket = $cluster->openBucket("default");

echo "Getting non-existent key. Should fail\n";
try {
    $bucket->get('non-exist-document');
} catch (CouchbaseException $ex) {
    if ($ex->getCode() != COUCHBASE_KEY_ENOENT) {
        throw new Exception("GRRR");
    }
    printf("Error: %s (0x%x)\n", $ex->getMessage(), $ex->getCode());
}

echo "Upserting...\n";
$bucket->upsert("new_document", array("foo" => "bar"));
echo "Getting\n";
$result = $bucket->get("new_document");
var_dump((array)$result->value);
echo "Foo is: " . $result->value->foo . "\n";

The output is

Getting non-existent key. Should fail
Error: LCB_KEY_ENOENT: The key does not exist on the server (0xd)
Upserting...
Getting
array(1) {
  ["foo"]=>
  string(3) "bar"
}
Foo is: bar

#18

The problem is the different behavior with query.

<?php
$cluster = new CouchbaseCluster("couchbase://localhost");
$bucket = $cluster->openBucket("odm-test");


echo "Upserting...\n";
$bucket->upsert("new_document", array("foo" => "bar"));
$result = $bucket->get("new_document");
var_dump($result->value);

$result = $bucket->query(\CouchbaseN1qlQuery::fromString("SELECT * FROM `odm-test` WHERE meta().id = 'new_document'"));
var_dump($result->rows);

$bucket->upsert("new_document", '{"name": "Sylvain"}');
$result = $bucket->get("new_document");
var_dump($result->value);

$result = $bucket->query(\CouchbaseN1qlQuery::fromString("SELECT * FROM `odm-test` WHERE meta().id = 'new_document'"));
var_dump($result->rows);

Output :

Upserting...
/home/srm/test.php:9:
class stdClass#4 (1) {
  public $foo =>
  string(3) "bar"
}
/home/srm/test.php:12:
array(1) {
  [0] =>
  class stdClass#8 (1) {
    public $odm-test =>
    class stdClass#7 (1) {
      public $foo =>
      string(3) "bar"
    }
  }
}
/home/srm/test.php:16:
string(19) "{"name": "Sylvain"}"
/home/srm/test.php:19:
array(1) {
  [0] =>
  class stdClass#7 (1) {
    public $odm-test =>
    class stdClass#8 (1) {
      public $name =>
      string(7) "Sylvain"
    }
  }
}

#19

what is different? when you store a string, you will get a string back, when you store an object, it will be transparently encoded as JSON object, and you would get the object back.

result of the query wraps the objects into a map, because you could query multiple buckets in the single query, but inside, it still the same representation of the object.


#20

The difference is “query” decode json and “get” don’t do this.