Geo-spatial queries with BigchainDB 2.0
How to create custom blockchain indexes?
BigchainDB is the blockchain database but little has been said about the database aspect of it. An earlier post discussed how to directly query the blockchain data stored by BigchainDB. That sure gives a lot of insight into how to fully leverage the power of MongoDB to execute complex queries but doesn’t necessarily cover all use cases of querying data, for eg. consider a situation wherein you wish to store geo-spatial data in BigcahinDB and wish to use spatial queries. Even when querying MongoDB directly the ability is limited by the indexes BigchainDB creates. If only there was way to tell BigchainDB what custom indexes to create the problem would be solved! I hate to break it to you but there’s no functionality in the current version that would allow you to do that. You might be wondering, did you create a post with a misleading title just to tell us that it can’t be done! Well not quite, one can always bend the system to their will, its just the amount of effort that differs. In this case the effort required to create custom indexes is quite low so let try to create and query spacial indexes.
Users can refer the guide here to setup a single node network. If you face issues then head over to gitter and complain!
At this point I assume that everything is installed but nothing has been started except MongoDB. So before we move on further to create custom indexes lets define our schema first.
Decide your schema
BigchainDB allows you to store asset
and metadata
in CREATE
transaction and metadata
in TRASFER
transaction. You are free to choose the kind of the json objects you wish to store. Let’s say you are doing shipment tracking for OnePlus wherein you create an asset on BigchainDB using the create transaction (refer the code , I just changed the asset
and metadata
values),
prepared_creation_tx = bdb.transactions.prepare(
operation='CREATE',
signers=oneplus_factory.public_key,
asset={"IMEI": "MY_NEW_ONEPLUS_6",
"order_number": "F3J9I02EO93"},
metadata={
"location": {
"type": "Point",
"coordinates": [23.113550, 113.239171]
}
},
)
Later we track the further movements,
prepared_transfer_tx = bdb.transactions.prepare(
operation='TRANSFER',
asset=transfer_asset,
inputs=transfer_input,
recipients=shipping_port_china.public_key,
metadata={
"location": {
"type": "Point",
"coordinates": [22.170872, 113.578749]
}
},
)
So our asset
and metadata
schema is defined! Now we move back to our console. As of now nothing is running.
Lets configure, initialize and start BigchainDB,
$ bigcahindb -y configure
Configuration written to /root/.bigchaindb
Ready to go!$ bigchiandb init
INFO:bigchaindb.config_utils:Configuration loaded from `/root/.bigchaindb`
INFO:bigchaindb.backend.localmongodb.schema:Create database `bigchain`.
INFO:bigchaindb.backend.localmongodb.schema:Create `transactions`
...
The bigchaindb init
command creates collections and indexes required by BigchainDB for storing it’s data. This is where we take a little detour i.e. apart from the indexes created by BigchainDB we go into the mongo console and manually create our spatial index,
> use bigchain
> show collections
assets
blocks
metadata
pre_commit
transactions
utxos
validators
The asset field specified in the CREATE
transaction is stored in the assets
collection and metadata
field specified in the CREATE
and TRANSFER
transaction is store in the metadata
collection. Since we know where the metadata
json is stored where create our spatial index,
> db.metadata.createIndex( { location: "2dsphere" } )
After which we start our system,
$ nohup tendermint node > tendermint.log &$ nohup bigchiandb start > bigchaindb.log &
Now, you can start posting transaction with the above discussed schema and they will automatically get indexed using the spatial index we created above. It is apparent that one can create any number of different indexes (but I would suggest to tread carefully!).
Since the indexes are in place you can probably revisit this post and create your desired queries.