mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Feat/105/secondary indexes inputs outputs (#1125)
* Added inputs/outputs secondary indexes for rethinkdb Added tests. * Added inputs/outputs secondary indexes for mongodb Fixed tests. * fixed comment
This commit is contained in:
parent
d49b06933a
commit
6fd8c7a20b
@ -143,6 +143,10 @@ def get_asset_by_id(conn, asset_id):
|
||||
@register_query(MongoDBConnection)
|
||||
def get_spent(conn, transaction_id, output):
|
||||
cursor = conn.db['bigchain'].aggregate([
|
||||
{'$match': {
|
||||
'block.transactions.inputs.fulfills.txid': transaction_id,
|
||||
'block.transactions.inputs.fulfills.output': output
|
||||
}},
|
||||
{'$unwind': '$block.transactions'},
|
||||
{'$match': {
|
||||
'block.transactions.inputs.fulfills.txid': transaction_id,
|
||||
@ -157,12 +161,9 @@ def get_spent(conn, transaction_id, output):
|
||||
@register_query(MongoDBConnection)
|
||||
def get_owned_ids(conn, owner):
|
||||
cursor = conn.db['bigchain'].aggregate([
|
||||
{'$match': {'block.transactions.outputs.public_keys': owner}},
|
||||
{'$unwind': '$block.transactions'},
|
||||
{'$match': {
|
||||
'block.transactions.outputs.public_keys': {
|
||||
'$elemMatch': {'$eq': owner}
|
||||
}
|
||||
}}
|
||||
{'$match': {'block.transactions.outputs.public_keys': owner}}
|
||||
])
|
||||
# we need to access some nested fields before returning so lets use a
|
||||
# generator to avoid having to read all records on the cursor at this point
|
||||
|
@ -63,6 +63,18 @@ def create_bigchain_secondary_index(conn, dbname):
|
||||
.create_index('block.transactions.transaction.asset.id',
|
||||
name='asset_id')
|
||||
|
||||
# secondary index on the public keys of outputs
|
||||
conn.conn[dbname]['bigchain']\
|
||||
.create_index('block.transactions.outputs.public_keys',
|
||||
name='outputs')
|
||||
|
||||
# secondary index on inputs/transaction links (txid, output)
|
||||
conn.conn[dbname]['bigchain']\
|
||||
.create_index([
|
||||
('block.transactions.inputs.fulfills.txid', ASCENDING),
|
||||
('block.transactions.inputs.fulfills.output', ASCENDING),
|
||||
], name='inputs')
|
||||
|
||||
|
||||
def create_backlog_secondary_index(conn, dbname):
|
||||
logger.info('Create `backlog` secondary index.')
|
||||
|
@ -111,21 +111,22 @@ def _get_asset_create_tx_query(asset_id):
|
||||
|
||||
@register_query(RethinkDBConnection)
|
||||
def get_spent(connection, transaction_id, output):
|
||||
# TODO: use index!
|
||||
return connection.run(
|
||||
r.table('bigchain', read_mode=READ_MODE)
|
||||
.concat_map(lambda doc: doc['block']['transactions'])
|
||||
.filter(lambda transaction: transaction['inputs'].contains(
|
||||
lambda input: input['fulfills'] == {'txid': transaction_id, 'output': output})))
|
||||
.get_all([transaction_id, output], index='inputs')
|
||||
.concat_map(lambda doc: doc['block']['transactions'])
|
||||
.filter(lambda transaction: transaction['inputs'].contains(
|
||||
lambda input_: input_['fulfills'] == {'txid': transaction_id, 'output': output})))
|
||||
|
||||
|
||||
@register_query(RethinkDBConnection)
|
||||
def get_owned_ids(connection, owner):
|
||||
# TODO: use index!
|
||||
return connection.run(
|
||||
r.table('bigchain', read_mode=READ_MODE)
|
||||
.concat_map(lambda doc: doc['block']['transactions'])
|
||||
.filter(lambda tx: tx['outputs'].contains(
|
||||
.get_all(owner, index='outputs')
|
||||
.distinct()
|
||||
.concat_map(lambda doc: doc['block']['transactions'])
|
||||
.filter(lambda tx: tx['outputs'].contains(
|
||||
lambda c: c['public_keys'].contains(owner))))
|
||||
|
||||
|
||||
|
@ -66,6 +66,31 @@ def create_bigchain_secondary_index(connection, dbname):
|
||||
.table('bigchain')
|
||||
.index_create('asset_id', r.row['block']['transactions']['asset']['id'], multi=True))
|
||||
|
||||
# secondary index on the public keys of outputs
|
||||
# the last reduce operation is to return a flatten list of public_keys
|
||||
# without it we would need to match exactly the public_keys list.
|
||||
# For instance querying for `pk1` would not match documents with
|
||||
# `public_keys: [pk1, pk2, pk3]`
|
||||
connection.run(
|
||||
r.db(dbname)
|
||||
.table('bigchain')
|
||||
.index_create('outputs',
|
||||
r.row['block']['transactions']
|
||||
.concat_map(lambda tx: tx['outputs']['public_keys'])
|
||||
.reduce(lambda l, r: l + r), multi=True))
|
||||
|
||||
# secondary index on inputs/transaction links (txid, output)
|
||||
connection.run(
|
||||
r.db(dbname)
|
||||
.table('bigchain')
|
||||
.index_create('inputs',
|
||||
r.row['block']['transactions']
|
||||
.concat_map(lambda tx: tx['inputs']['fulfills'])
|
||||
.with_fields('txid', 'output')
|
||||
.map(lambda fulfills: [fulfills['txid'],
|
||||
fulfills['output']]),
|
||||
multi=True))
|
||||
|
||||
# wait for rethinkdb to finish creating secondary indexes
|
||||
connection.run(
|
||||
r.db(dbname)
|
||||
|
@ -21,8 +21,8 @@ def test_init_creates_db_tables_and_indexes():
|
||||
assert sorted(collection_names) == ['backlog', 'bigchain', 'votes']
|
||||
|
||||
indexes = conn.conn[dbname]['bigchain'].index_information().keys()
|
||||
assert sorted(indexes) == ['_id_', 'asset_id', 'block_timestamp',
|
||||
'transaction_id']
|
||||
assert sorted(indexes) == ['_id_', 'asset_id', 'block_timestamp', 'inputs',
|
||||
'outputs', 'transaction_id']
|
||||
|
||||
indexes = conn.conn[dbname]['backlog'].index_information().keys()
|
||||
assert sorted(indexes) == ['_id_', 'assignee__transaction_timestamp',
|
||||
@ -81,8 +81,8 @@ def test_create_secondary_indexes():
|
||||
|
||||
# Bigchain table
|
||||
indexes = conn.conn[dbname]['bigchain'].index_information().keys()
|
||||
assert sorted(indexes) == ['_id_', 'asset_id', 'block_timestamp',
|
||||
'transaction_id']
|
||||
assert sorted(indexes) == ['_id_', 'asset_id', 'block_timestamp', 'inputs',
|
||||
'outputs', 'transaction_id']
|
||||
|
||||
# Backlog table
|
||||
indexes = conn.conn[dbname]['backlog'].index_information().keys()
|
||||
|
@ -85,6 +85,10 @@ def test_create_secondary_indexes():
|
||||
'transaction_id')) is True
|
||||
assert conn.run(r.db(dbname).table('bigchain').index_list().contains(
|
||||
'asset_id')) is True
|
||||
assert conn.run(r.db(dbname).table('bigchain').index_list().contains(
|
||||
'inputs')) is True
|
||||
assert conn.run(r.db(dbname).table('bigchain').index_list().contains(
|
||||
'outputs')) is True
|
||||
|
||||
# Backlog table
|
||||
assert conn.run(r.db(dbname).table('backlog').index_list().contains(
|
||||
|
Loading…
x
Reference in New Issue
Block a user