DocumentFragment.content

It is may be a bug , or I don’t know how to use

I have a document like :

{
   "a" : {
      "150": "A",
      "820":"B"
   }
}

the following N1QL query can select a.150

SELECT a.`150` FROM myBucket

But in nodejs client , I see that the following code works to get it

bucket.lookupIn(key).get('a.`150`')

OR

bucket.lookupIn(key).get('a.150')

But the following not works

bucket.lookupIn(key).exists('a.150').execute(
    function(err, result) {
        console.log( result.content('a.150'))
    }
);

result.content('a.150') always is null

Using back-ticks, e.g.

a.`150`

is the standard way in N1QL to refer to field names that have special characters in them, such as space or dash (’ ’ or ‘-’). I suspect that the node.js SDK doesn’t like a numeric field name, hence the need for back-ticks.

Does the following work?

bucket.lookupIn(key).exists('a.`150`').execute(
    function(err, result) {
        console.log( result.content('a.150'))
    }
);

The result of result.content('a.150') is null if exists and exception if not exists but result.exists('a.150') is true/false , Is it a good behavior? If I want to check existence of a field I must do bucket.lookupIn.exists the result.exists

Hey @socketman2016,

It’s worth recognizing that you can call the exists(...) method on your result object to determine if a value existed after executing a get(...) operation for the lookup. Using the request-time exists operation itself is primarily useful as an optimization when the existence of an element is important, but its specific value is not.

Cheers, Brett

Using the request-time exists operation itself is primarily useful as an optimization when the existence of an element is important, but its specific value is not.

Yes I know , But to check existence is it true ?

bucket.lookupIn(key).exists('a.`150`').execute(
    function(err, result) {
        console.log( result.exists('a.150')) //TRUE or FALSE
    }
);

As

bucket.lookupIn(key).exists('a.`150`').execute(
    function(err, result) {
        console.log( result.content('a.150')) //Null or throws
    }
);

Hey @socketman2016,

Both of those are more or less identical in their behaviour. Typically I prefer to rely on the exists method as handling a boolean is simpler than catching an exception, but both are going to give the same results. I’d say to base it around your use-case. If the element not being found is a fatal error, simply use .content(...) and allow it to fail, alternatively if it missing is a standard case and you wish to handle it, you can check first using .exists(...).

Cheers, Brett

FYI, I checked the N1QL parser, and unless you enclose a field name in back ticks, the name must start with a letter on underscore. Thus ‘a.150’ should not be valid, you need to enclose 150 in back ticks.

@eben but bucket.lookupIn(key).get('a.150') works for me , Must I change it to

bucket.lookupIn(key).get('a.`150`')

https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/identifiers.html

un-escaped Identifies can’t start with numeric character, differentiate constant vs fields vs nested fields.

The following example gives how to escaped identifiers handles with dot in fields vs nested objects

 insert into default values("f1",{"10":{"5": "xyz"}, "10.5":"pqr"});
SELECT 10.5 AS c1, `10`.`5` aS c2, `10.5`  AS c3 FROM default USE KEYS "f1";

"results": [
    {
        "c3": "pqr",
        "c1": 10.5,
        "c2": "xyz"
    }

Why it works? :smile:

 bucket.lookupIn(key).get('a.150')

Hey @socketman2016,

The lookupIn method is using an API called ‘sub-document operations’ that the SDKs support. The grammar for referencing fields in sub-document is slightly different than that of referencing fields in N1QL. That’s the reason for the difference in needing the backticks or not.

Cheers, Brett

Why it works? :smile:

bucket.lookupIn(key).get('a.150')

Good question! :slight_smile: I suspect that the SDK is cleaning things up to make it work. In the query workbench, if you do:

select a.150 from bucket;

You get the error:

[
  {
    "code": 3000,
    "msg": "syntax error - at 150",
    "query_from_user": "select a.150 from bucket;"
  }
]