Reading Indexes

You use Store.index_iterator() to retrieve table rows using a table's indexes. Just as when you use table_terator to read table rows using a table's primary key(s), when reading using indexes you can set options such as field ranges, traversal direction, and so forth. By default, index scans return entries in forward order.

For example, suppose you defined a table like this:

CREATE TABLE myTable (
    surname STRING,
    familiarName STRING,
    userID STRING,
    phonenumber STRING,
    address STRING,
    email STRING,
    dateOfBirth STRING,
    PRIMARY KEY (SHARD(surname, familiarName), userID)
) 
CREATE INDEX DoB ON myTable (dateOfBirth) 

This creates an index named DoB for table myTable based on the value of the dateOfBirth field. To scan through that index, do the following:

def display_row(row):
    try:
            print "Retrieved row:"
            print "\tSurname: %s" % row['surname']
            print "\tFamiliar Name: %s" % row['familiarName']
            print "\tUser ID: %s" % row['userID']
            print "\tPhone: %s" % row['phonenumber']
            print "\tAddress: %s" % row['address']
            print "\tEmail: %s" % row['email']
            print "\tDate of Birth: %s" % row['dateOfBirth']
            print "\n"
    except KeyError, ke:
        logging.error("Row display failed. Bad key: %s" % ke.message)


def do_store_ops(store):

    key_d = {}

    try:
        row_list = store.index_iterator("myTable", "DoB",
                                        key_d, False)
        if not row_list:
            logging.debug("Table retrieval failed")
        else:
            logging.debug("Table retrieval succeeded.")
            for r in row_list:
                display_row(r)
    except IllegalArgumentException, iae:
        logging.error("Table retrieval failed.")
        logging.error(iae.message) 

In the previous example, the code examines every row indexed by the DoB index. A more likely, and useful, example in this case would be to limit the rows returned through the use of a field range. You do that by constructing a FieldRange object. When you do this, you must specify the field to base the range on. Recall that an index can be based on more than one table field, so the field name you give the object must be one of the indexed fields.

For example, if the rows hold dates in the form of yyyy-mm-dd, you could retrieve all the people born in the month of May, 1994 in the following way. This index only examines one field, dateOfBirth, so we give that field name to the FieldRange object:

def display_row(row):
    try:
            print "Retrieved row:"
            print "\tSurname: %s" % row['surname']
            print "\tFamiliar Name: %s" % row['familiarName']
            print "\tUser ID: %s" % row['userID']
            print "\tPhone: %s" % row['phonenumber']
            print "\tAddress: %s" % row['address']
            print "\tEmail: %s" % row['email']
            print "\tDate of Birth: %s" % row['dateOfBirth']
            print "\n"
    except KeyError, ke:
        logging.error("Row display failed. Bad key: %s" % ke.message)


def do_store_ops(store):

    key_d = {}

    field_range = FieldRange({
                             ONDB_FIELD : "dateOfBirth",
                             ONDB_START_VALUE : "1994-05-01",
                             ONDB_END_VALUE : "1994-05-30",
                             # These next two are the default values,
                             # so are not really needed.
                             ONDB_START_INCLUSIVE : True,
                             ONDB_END_INCLUSIVE : True
                             })

    mro = MultiRowOptions({ONDB_FIELD_RANGE : field_range})

    try:
        row_list = store.index_iterator("myTable", "DoB",
                                        key_d, False, mro)
        if not row_list:
            logging.debug("Table retrieval failed")
        else:
            logging.debug("Table retrieval succeeded.")
            for r in row_list:
                display_row(r)
    except IllegalArgumentException, iae:
        logging.error("Table retrieval failed.")
        logging.error(iae.message)