README.md in dynamodb_geo-0.0.2 vs README.md in dynamodb_geo-0.1.0

- old
+ new

@@ -1,9 +1,129 @@ # DynamoDB_Geo +## DynamoDB +This is an attempt at storing and querying geohash data in DynamoDB. +We store objects in DynamoDB, when we query, we look for a customizable number of stored items by zooming out exactly one level. Returned in an attempt at the closest items first. -# Geohashing +Items are searched as the following. +Given the lat, long we calculate a hash 9x0qz. We go up one level to 9x0q and calculate all neighbouring hashes. + + 9x0p 9x0r 9x0x + 9x0n 9x0q 9x0w => ["9x0q", "9x0r", "9x0x", "9x0w", "9x0t", "9x0m", "9x0j", "9x0n", "9x0p"] + 9x0j 9x0m 9x0t + +From this, we ask DynamoDB starting from our own cell, going north, and wrapping clockwise for all objects in these cells up to a configurable number of objects. +We then calculate the neighbours of our more local hash 9x0qz, and sort the results of the larger hashes using similar rules. + + 9x0rn 9x0rp 9x0x0 + 9x0qy 9x0qz 9x0wb => ["9x0qz", "9x0rp", "9x0x0", "9x0wb", "9x0w8", "9x0qx", "9x0qw", "9x0qy", "9x0rn"] + 9x0qw 9x0qx 9x0w8 + +Using the same pattern as before (Middle -> North -> Clockwise), we sort the returned stores giving priority to the localization. + +### Real talk +I know this isn't the most wonderful way to do this, I am still trying to think of something better. Currently it uses up to 8 queries to DynamoDB, I'd like to cut that down to a single query. + +There is a similar library written in Java and JS, but it uses Google S2 for the Geohashing, which has properties that allow them to do the zoom-out technique with a single query, however Google S2 does not exist as a C library (or Ruby library for that matter). The other alternative is Uber H3, however it has the same issues of not being C, or Ruby. + +If we were able to use a unique but deterministic way to calcuate the range key based off of the hash key that would allow us to query every single larger cell in a single batch query. I am currently thinking of more clever ways to do this - obviously I am open to suggestions. + +## Objects +### DynamodbManager + +**Attributes** +table_name: +Sets the DynamoDB Table Name + +hash_key: +Sets the name of the primary hash attribute + +range_key: +Sets the name of the sort/range attribute + +geohash_key: +Sets the name of the localized hash attribute + +geojson_key: +Sets the name of the metadata attribute + +hash_key_length: +Sets size of the outer hash length + +local_area_size: +Sets the size of the inner hash length + +max_item_return: +Sets the max number of items to return + +**Methods** +Initialization + + Description: Creates a new DynamodbManager object. Inputs are variables to your AWS account. + If access_key_id and secret_access_key are provided they are used. + If not provided, it falls back to ENV variables, then secret credential storage (profile name). + All arguments are keyword arguments + Input: region => String + table_name => String + access_key_id => String + secret_access_key => String + profile_name => 'default' + Output: Aws::DynamoDB::Client + + #new => Object + +Building and describing a DynamoDB Table + + Description: Shows the current configured table, or creates a table to configured as requested + Input: + Output: Aws::DynamoDB::Types::DescribeTableOutput + + #table => Object + +Creating a new item + + Description: Inserts a new item + Input: Store + Output: Aws::DynamoDB::Types::PutItemOutput + + #put_store => Object + +Querying stores + + Description: Look for stores dependent on the input Lat, Long (as described above) + Input: Store + Output: Array[Store] + + #get_stores => Array[Store] + +### Store + +**Methods** +Initialization + + Description: Initialization + Input: Hash => { + latitude # Required + longitude # Required + address + city + state + zip + area_code + phone + name + geohash # Calculated based on lat,long if not provided + } + Output: Store + + #new => Store + +### DynamodbGeo +This only exists as a quick and easy way to create a DynamodbManager. The only method is `.new` and it passes all arguments along to DynamodbManager and returns an instance of DynamodbManager + + +## Geohashing Includes a Geohash implimentation written in C <https://github.com/simplegeo/libgeohash> ### Methods @@ -41,15 +161,29 @@ Input: Geohash => String Output: Array[Geocoord] Geohash.neighbours(hash) => Array[Geohash] +Viewing one of my neighbours + + Description: Takes in a Geohash and shows the neighbour in the cardinal direction + NORTH = 0 + EAST = 1 + SOUTH = 2 + WEST = 3 + Input: Geohash => String + Direction => Integer + Output: Geohash + + Geohash.neighbour(hash) => Geohash + Get width and height about a specific precision Description: Takes in a precision value, returns the height and width of the box Input: precision => Number Output: Dimension => Object Geohash.dimensions(precision) => Dimension +### Objects #### Geocoord(Object) => attr_accessor: :latitude, :longitude, :north, :south, :east, :west, :dimension #### Dimension(Object) => attr_accessor: :length, :width