mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Merge pull request #1131 from bigchaindb/fix-asset_id-index
Fix asset id index
This commit is contained in:
commit
47d6b8038b
@ -1,7 +1,6 @@
|
|||||||
"""Query implementation for MongoDB"""
|
"""Query implementation for MongoDB"""
|
||||||
|
|
||||||
from time import time
|
from time import time
|
||||||
from itertools import chain
|
|
||||||
|
|
||||||
from pymongo import ReturnDocument
|
from pymongo import ReturnDocument
|
||||||
from pymongo import errors
|
from pymongo import errors
|
||||||
@ -86,39 +85,30 @@ def get_blocks_status_from_transaction(conn, transaction_id):
|
|||||||
|
|
||||||
@register_query(MongoDBConnection)
|
@register_query(MongoDBConnection)
|
||||||
def get_txids_filtered(conn, asset_id, operation=None):
|
def get_txids_filtered(conn, asset_id, operation=None):
|
||||||
parts = []
|
match_create = {
|
||||||
|
'block.transactions.operation': 'CREATE',
|
||||||
|
'block.transactions.id': asset_id
|
||||||
|
}
|
||||||
|
match_transfer = {
|
||||||
|
'block.transactions.operation': 'TRANSFER',
|
||||||
|
'block.transactions.asset.id': asset_id
|
||||||
|
}
|
||||||
|
|
||||||
if operation in (Transaction.CREATE, None):
|
if operation == Transaction.CREATE:
|
||||||
# get the txid of the create transaction for asset_id
|
match = match_create
|
||||||
cursor = conn.db['bigchain'].aggregate([
|
elif operation == Transaction.TRANSFER:
|
||||||
{'$match': {
|
match = match_transfer
|
||||||
'block.transactions.id': asset_id,
|
else:
|
||||||
'block.transactions.operation': 'CREATE'
|
match = {'$or': [match_create, match_transfer]}
|
||||||
}},
|
|
||||||
{'$unwind': '$block.transactions'},
|
|
||||||
{'$match': {
|
|
||||||
'block.transactions.id': asset_id,
|
|
||||||
'block.transactions.operation': 'CREATE'
|
|
||||||
}},
|
|
||||||
{'$project': {'block.transactions.id': True}}
|
|
||||||
])
|
|
||||||
parts.append(elem['block']['transactions']['id'] for elem in cursor)
|
|
||||||
|
|
||||||
if operation in (Transaction.TRANSFER, None):
|
pipeline = [
|
||||||
# get txids of transfer transaction with asset_id
|
{'$match': match},
|
||||||
cursor = conn.db['bigchain'].aggregate([
|
{'$unwind': '$block.transactions'},
|
||||||
{'$match': {
|
{'$match': match},
|
||||||
'block.transactions.asset.id': asset_id
|
{'$project': {'block.transactions.id': True}}
|
||||||
}},
|
]
|
||||||
{'$unwind': '$block.transactions'},
|
cursor = conn.db['bigchain'].aggregate(pipeline)
|
||||||
{'$match': {
|
return (elem['block']['transactions']['id'] for elem in cursor)
|
||||||
'block.transactions.asset.id': asset_id
|
|
||||||
}},
|
|
||||||
{'$project': {'block.transactions.id': True}}
|
|
||||||
])
|
|
||||||
parts.append(elem['block']['transactions']['id'] for elem in cursor)
|
|
||||||
|
|
||||||
return chain(*parts)
|
|
||||||
|
|
||||||
|
|
||||||
@register_query(MongoDBConnection)
|
@register_query(MongoDBConnection)
|
||||||
|
@ -60,8 +60,7 @@ def create_bigchain_secondary_index(conn, dbname):
|
|||||||
|
|
||||||
# secondary index for asset uuid, this field is unique
|
# secondary index for asset uuid, this field is unique
|
||||||
conn.conn[dbname]['bigchain']\
|
conn.conn[dbname]['bigchain']\
|
||||||
.create_index('block.transactions.transaction.asset.id',
|
.create_index('block.transactions.asset.id', name='asset_id')
|
||||||
name='asset_id')
|
|
||||||
|
|
||||||
# secondary index on the public keys of outputs
|
# secondary index on the public keys of outputs
|
||||||
conn.conn[dbname]['bigchain']\
|
conn.conn[dbname]['bigchain']\
|
||||||
|
23
tests/backend/mongodb/test_indexes.py
Normal file
23
tests/backend/mongodb/test_indexes.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import pytest
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.bdb
|
||||||
|
|
||||||
|
|
||||||
|
def test_asset_id_index():
|
||||||
|
from bigchaindb.backend.mongodb.query import get_txids_filtered
|
||||||
|
from bigchaindb.backend import connect
|
||||||
|
|
||||||
|
# Passes a mock in place of a connection to get the query params from the
|
||||||
|
# query function, then gets the explain plan from MongoDB to test that
|
||||||
|
# it's using certain indexes.
|
||||||
|
|
||||||
|
m = MagicMock()
|
||||||
|
get_txids_filtered(m, '')
|
||||||
|
pipeline = m.db['bigchain'].aggregate.call_args[0][0]
|
||||||
|
run = connect().db.command
|
||||||
|
res = run('aggregate', 'bigchain', pipeline=pipeline, explain=True)
|
||||||
|
stages = (res['stages'][0]['$cursor']['queryPlanner']['winningPlan']
|
||||||
|
['inputStage']['inputStages'])
|
||||||
|
indexes = [s['inputStage']['indexName'] for s in stages]
|
||||||
|
assert set(indexes) == {'asset_id', 'transaction_id'}
|
Loading…
x
Reference in New Issue
Block a user