N1QL python iter

Hi
Was looking at this and with an issue I hit wanted to get clarification.

Is the default object returned by NQL query a DICT not a string/list ? As it prevents certain operations based on how data object is stored - eg string manipulation.

result = cb.n1ql_query(query)
for row in result:
record=str(row)
second_field = record.split(‘:’)[1] # split the string by : then select the second field
second_field_array.append(second_field) # Add the
print(Counter(second_field_array))

Is there a better way to do this ?

thanks

The default object returned by Bucket.n1ql_query or Cluster.n1ql_query is a couchbase.n1ql.N1QLRequest object, as described here:

https://docs.couchbase.com/sdk-api/couchbase-python-client-2.5.5/api/n1ql.html#couchbase.n1ql.N1QLRequest

This simply implements the iterator protocol. Each result returned by next() from this iterator is simply a transcoded version of the data contained in a single N1QL result row. As N1QL requests return a JSON result, this would by default be a Python object, i.e. a list, value or dictionary, as json.loads would produce when decoding JSON.

It looks like you’re turning the JSON structure back into a string and then performing string operations on the stringified data. It would seem likely that any manipulations you need to do that involve parsing the JSON representation would be better done using the parsed version, i.e. the native Python objects.

In this case, it looks like you are retrieving the value of the first entry in the returned dictionary. You can get this as follows:

row.values().iter().next(<default value>) . # <default value> will be returned if there are no entries

Or if you know this value will be associated with a specific key (which would most likely be more reliable), then you can write:

row.get("key", <default value>) # <default value> will be returned if the key is not present.

In SDK2 it is up the end-user to map values back to a given class, either using their own transcoder or by taking the already decoded values and further marshalling them to the target data type. We are working on a new transcoding protocol for SDK3 that will formalise this further.

Hope that helps,

Ellis

Hi Ellis
Maybe an example would help ?

The issue is a lot of queries on multi docs need a list of docs first. So need N1Ql to identify those docs/objects. Once identified need to loop though and process.
My default its returned as a DICT object - which stringify or other operators are not valid against. So has to be converted from a DICT to STR

Can you show a better example of how to use - simply return all docs of a certain type within a bucket and sum the distinct counts of those doc types based on either meta_id or an attribute within the doc.

thx