No Exception thrown when client queried a bin which is not indexed

The Aerospike Knowledge Base has moved to https://support.aerospike.com. Content on https://discuss.aerospike.com is being migrated to either https://support.aerospike.com or https://docs.aerospike.com. Maintenance on articles stored in this repository ceased on December 31st 2022 and this article may be stale. If you have any questions, please do not hesitate to raise a case via https://support.aerospike.com.

No Exception thrown when querying a bin which is not indexed

Problem Description

Although the query() method has been invoked, unless the returned RecordSet is iterated through (by calling rs.next() ), no error will be returned in the event that the query is issued against a bin that has not been indexed. An example of query calling code is shown below:

private void queryRecords(String aInNameSpaceName, String aInSetName, Filter aInFilter) {
		
       	try {	
	    	Statement stmt = new Statement();
	    	stmt.setNamespace(aInNameSpaceName);
	    	stmt.setSetName(aInSetName);
//	    	stmt.setFilter(Filter.range("pKey8chars", Long.MIN_VALUE, Long.MAX_VALUE));
	    	stmt.setFilter(aInFilter);
    		
    		RecordSet rs = client.query(null, stmt);
//    	        while (rs.next()) {
//    	    	  System.out.println("got a record");
//    	    }
    		System.out.println("after query");
    	} catch (AerospikeException ae) {
    		System.out.println("catch a exception: ");
    		System.out.println(ae.getMessage());
    	}
    }

Explanation

This is an expected behaviour. The query() method sends the query command to all server nodes, initializes an empty RecordSet and returns. It does not iterate through the records themselves.

The completion of query() does not indicate that all records have been retrieved from the server nodes. The returned RecordSet is a cursor with a limited buffer size and this cursor must be iterated on to drain that buffer, so more records can be retrieved from the servers.

Basically, query() does the following:

  • Initialize empty RecordSet.

  • Send a query command to each server node and each command runs in a separate thread.

  • Returns an empty RecordSet.

At this point the servers have not returned anything, so the (201) INDEX_NOT_FOUND error code has not been returned yet. When the server nodes return the error code, the parallel query node threads populate the RecordSet concurrent queue with that error code.

It would be inefficient to wait until all servers respond because some servers will respond quicker than others and that would require waiting for the slowest server to respond before allowing the user to iterate on records returned by the faster server nodes.

It’s also inefficient to wait for one server to respond because that requires additional atomic calls and this might help only with this very specific case. It would also fail to handle the case where most nodes have the proper index, while one node’s index create failed or has not completed yet. There are numerous other query errors that can occur later and these errors must be handled on the RecordSet iteration.

Therefore, the query can fail after the query() method completes and further exceptions must be handled during RecordSet iteration. Only initial connection errors will result in an exception in query() but all server responses have to be handled when iterating through RecordSet.

Keywords

EXCEPTION QUERY INDEX_NOT_FOUND 201

Timestamp

July 2021