Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimize search assets query #199

Open
wants to merge 2 commits into
base: eclipse-build
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 3 additions & 15 deletions das_api/src/api/api_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use digital_asset_types::{
get_proof_for_asset, get_token_accounts, search_assets,
},
rpc::{
filter::{AssetSortBy, SearchConditionType},
filter::SearchConditionType,
response::{GetGroupingResponse, TokenAccountList},
OwnershipModel, RoyaltyModel,
},
Expand Down Expand Up @@ -102,11 +102,6 @@ impl DasApi {
if cursor.is_some() {
return Err(DasApiError::PaginationError);
}
if let Some(sort) = &sorting {
if sort.sort_by != AssetSortBy::Id {
return Err(DasApiError::PaginationSortingValidationError);
}
}
validate_pubkey(before.clone())?;
is_cursor_enabled = false;
}
Expand All @@ -115,21 +110,14 @@ impl DasApi {
if cursor.is_some() {
return Err(DasApiError::PaginationError);
}
if let Some(sort) = &sorting {
if sort.sort_by != AssetSortBy::Id {
return Err(DasApiError::PaginationSortingValidationError);
}
}

validate_pubkey(after.clone())?;
is_cursor_enabled = false;
}

page_opt.limit = limit.map(|x| x as u64).unwrap_or(1000);
if is_cursor_enabled {
if let Some(sort) = &sorting {
if sort.sort_by != AssetSortBy::Id {
return Err(DasApiError::PaginationSortingValidationError);
}
if sorting.is_some() {
page_opt.cursor = Some(self.get_cursor(cursor)?);
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions digital_asset_types/src/dao/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,11 @@ impl SearchAssetsQuery {
// In theory, the owner_type=single check should be sufficient,
// however there is an old bug that has marked some non-NFTs as "single" with supply > 1.
// The supply check guarentees we do not include those.
conditions = conditions.add_option(Some(
conditions = conditions.add(
asset::Column::OwnerType
.eq(OwnerType::Single)
.and(asset::Column::Supply.lte(1)),
));
);
}
}
}
Expand Down
20 changes: 5 additions & 15 deletions digital_asset_types/src/dao/scopes/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,7 @@ where
.join(JoinType::LeftJoin, relation.def());

if let Some(col) = sort_by {
stmt = stmt
.order_by(col, sort_direction.clone())
.order_by(asset::Column::Id, sort_direction.clone());
stmt = stmt.order_by(col, sort_direction.clone())
}

let assets = paginate(pagination, limit, stmt, sort_direction, asset::Column::Id)
Expand Down Expand Up @@ -302,8 +300,7 @@ pub async fn get_related_for_assets(

// Get all creators for all assets in `assets_map``.
let creators = asset_creators::Entity::find()
.filter(asset_creators::Column::AssetId.is_in(ids))
.order_by_asc(asset_creators::Column::AssetId)
.filter(asset_creators::Column::AssetId.is_in(ids.clone()))
.order_by_asc(asset_creators::Column::Position)
.all(conn)
.await?;
Expand Down Expand Up @@ -331,7 +328,6 @@ pub async fn get_related_for_assets(
let ids = assets_map.keys().cloned().collect::<Vec<_>>();
let authorities = asset_authority::Entity::find()
.filter(asset_authority::Column::AssetId.is_in(ids.clone()))
.order_by_asc(asset_authority::Column::AssetId)
.all(conn)
.await?;
for a in authorities.into_iter() {
Expand Down Expand Up @@ -361,8 +357,7 @@ pub async fn get_related_for_assets(
let grouping_base_query = asset_grouping::Entity::find()
.filter(asset_grouping::Column::AssetId.is_in(ids.clone()))
.filter(asset_grouping::Column::GroupValue.is_not_null())
.filter(cond)
.order_by_asc(asset_grouping::Column::AssetId);
.filter(cond);

if options.show_collection_metadata {
let combined_group_query = grouping_base_query
Expand Down Expand Up @@ -417,9 +412,7 @@ pub async fn get_assets_by_condition(
}
stmt = stmt.filter(condition);
if let Some(col) = sort_by {
stmt = stmt
.order_by(col, sort_direction.clone())
.order_by(asset::Column::Id, sort_direction.clone());
stmt = stmt.order_by(col, sort_direction.clone())
}

let assets = paginate(pagination, limit, stmt, sort_direction, asset::Column::Id)
Expand Down Expand Up @@ -462,7 +455,6 @@ pub async fn get_by_id(
let (asset, data) = asset_data;
let authorities: Vec<asset_authority::Model> = asset_authority::Entity::find()
.filter(asset_authority::Column::AssetId.eq(asset.id.clone()))
.order_by_asc(asset_authority::Column::AssetId)
.all(conn)
.await?;
let mut creators: Vec<asset_creators::Model> = asset_creators::Entity::find()
Expand All @@ -482,8 +474,7 @@ pub async fn get_by_id(
// Older versions of the indexer did not have the verified flag. A group would be present if and only if it was verified.
// Therefore if verified is null, we can assume that the group is verified.
.add(asset_grouping::Column::Verified.is_null()),
)
.order_by_asc(asset_grouping::Column::AssetId);
);

let groups = if options.show_collection_metadata {
grouping_query
Expand Down Expand Up @@ -577,7 +568,6 @@ pub async fn get_asset_signatures(
let stmt = asset::Entity::find()
.distinct_on([(asset::Entity, asset::Column::Id)])
.filter(asset::Column::Id.eq(asset_id))
.order_by(asset::Column::Id, Order::Desc)
.limit(1);
let asset = stmt.one(conn).await?;
if let Some(asset) = asset {
Expand Down
1 change: 0 additions & 1 deletion digital_asset_types/src/dapi/common/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ pub fn build_transaction_signatures_response(

pub fn create_sorting(sorting: AssetSorting) -> (sea_orm::query::Order, Option<asset::Column>) {
let sort_column = match sorting.sort_by {
AssetSortBy::Id => Some(asset::Column::Id),
AssetSortBy::Created => Some(asset::Column::CreatedAt),
AssetSortBy::Updated => Some(asset::Column::SlotUpdated),
AssetSortBy::RecentAction => Some(asset::Column::SlotUpdated),
Expand Down
4 changes: 1 addition & 3 deletions digital_asset_types/src/rpc/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,14 @@ pub struct AssetSorting {
impl Default for AssetSorting {
fn default() -> AssetSorting {
AssetSorting {
sort_by: AssetSortBy::Id,
sort_by: AssetSortBy::None,
sort_direction: Some(AssetSortDirection::default()),
}
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
pub enum AssetSortBy {
#[serde(rename = "id")]
Id,
#[serde(rename = "created")]
Created,
#[serde(rename = "updated")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ snapshot_kind: text
"page": 1,
"items": [
{
"interface": "MplCoreAsset",
"id": "4FcFVJVPRsYoMjt8ewDGV5nipoK63SNrJzjrBHyXvhcz",
"interface": "MplCoreCollection",
"id": "9CSyGBw1DCVZfx621nb7UBM9SpVDsX1m9MaN6APCf1Ci",
"content": {
"$schema": "https://schema.metaplex.com/nft1.0.json",
"json_uri": "https://example.com/asset",
"json_uri": "https://example.com/collection",
"files": [],
"metadata": {
"name": "Test Asset",
"name": "Test Collection",
"symbol": ""
},
"links": {}
Expand All @@ -39,12 +39,7 @@ snapshot_kind: text
"seq": 0,
"leaf_id": 0
},
"grouping": [
{
"group_key": "collection",
"group_value": "9CSyGBw1DCVZfx621nb7UBM9SpVDsX1m9MaN6APCf1Ci"
}
],
"grouping": [],
"royalty": {
"royalty_model": "creators",
"target": null,
Expand All @@ -59,25 +54,27 @@ snapshot_kind: text
"delegated": false,
"delegate": null,
"ownership_model": "single",
"owner": "GzYvuu9aUYXmnardj4svbAcCNmefiaGu2E3knGw9NJQQ"
"owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7"
},
"mutable": true,
"burnt": false,
"plugins": {},
"mpl_core_info": {
"num_minted": 1,
"current_size": 1,
"plugins_json_version": 1
},
"external_plugins": []
},
{
"interface": "MplCoreCollection",
"id": "9CSyGBw1DCVZfx621nb7UBM9SpVDsX1m9MaN6APCf1Ci",
"interface": "MplCoreAsset",
"id": "4FcFVJVPRsYoMjt8ewDGV5nipoK63SNrJzjrBHyXvhcz",
"content": {
"$schema": "https://schema.metaplex.com/nft1.0.json",
"json_uri": "https://example.com/collection",
"json_uri": "https://example.com/asset",
"files": [],
"metadata": {
"name": "Test Collection",
"name": "Test Asset",
"symbol": ""
},
"links": {}
Expand All @@ -100,7 +97,12 @@ snapshot_kind: text
"seq": 0,
"leaf_id": 0
},
"grouping": [],
"grouping": [
{
"group_key": "collection",
"group_value": "9CSyGBw1DCVZfx621nb7UBM9SpVDsX1m9MaN6APCf1Ci"
}
],
"royalty": {
"royalty_model": "creators",
"target": null,
Expand All @@ -115,14 +117,12 @@ snapshot_kind: text
"delegated": false,
"delegate": null,
"ownership_model": "single",
"owner": "APrZTeVysBJqAznfLXS71NAzjr2fCVTSF1A66MeErzM7"
"owner": "GzYvuu9aUYXmnardj4svbAcCNmefiaGu2E3knGw9NJQQ"
},
"mutable": true,
"burnt": false,
"plugins": {},
"mpl_core_info": {
"num_minted": 1,
"current_size": 1,
"plugins_json_version": 1
},
"external_plugins": []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ snapshot_kind: text
"items": [
{
"interface": "ProgrammableNFT",
"id": "8t77ShMViat27Sjphvi1FVPaGrhFcttPAkEnLCFp49Bo",
"id": "42AYryUGNmJMe9ycBXZekkYvdTehgbtECHs7SLu5JJTB",
"content": {
"$schema": "https://schema.metaplex.com/nft1.0.json",
"json_uri": "https://cdn.hellomoon.io/public/silicons/metadata/1466.json",
"json_uri": "https://cdn.hellomoon.io/public/silicons/metadata/2835.json",
"files": [],
"metadata": {
"name": "SILICON #1466",
"name": "SILICON #2835",
"symbol": "SILI",
"token_standard": "ProgrammableNonFungible"
},
Expand Down Expand Up @@ -78,13 +78,13 @@ snapshot_kind: text
},
{
"interface": "ProgrammableNFT",
"id": "42AYryUGNmJMe9ycBXZekkYvdTehgbtECHs7SLu5JJTB",
"id": "8t77ShMViat27Sjphvi1FVPaGrhFcttPAkEnLCFp49Bo",
"content": {
"$schema": "https://schema.metaplex.com/nft1.0.json",
"json_uri": "https://cdn.hellomoon.io/public/silicons/metadata/2835.json",
"json_uri": "https://cdn.hellomoon.io/public/silicons/metadata/1466.json",
"files": [],
"metadata": {
"name": "SILICON #2835",
"name": "SILICON #1466",
"symbol": "SILI",
"token_standard": "ProgrammableNonFungible"
},
Expand Down
4 changes: 4 additions & 0 deletions migration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ mod m20240320_120101_add_mpl_core_info_items;
mod m20240520_120101_add_mpl_core_external_plugins_columns;
mod m20240718_161232_change_supply_columns_to_numeric;
mod m20241119_060310_add_token_inscription_enum_variant;
mod m20241209_100813_add_unique_index_for_asset_owner_and_supply;
mod m20241209_111604_add_index_for_asset_id_group_value_verified;

pub mod model;

Expand Down Expand Up @@ -99,6 +101,8 @@ impl MigratorTrait for Migrator {
Box::new(m20240520_120101_add_mpl_core_external_plugins_columns::Migration),
Box::new(m20240718_161232_change_supply_columns_to_numeric::Migration),
Box::new(m20241119_060310_add_token_inscription_enum_variant::Migration),
Box::new(m20241209_100813_add_unique_index_for_asset_owner_and_supply::Migration),
Box::new(m20241209_111604_add_index_for_asset_id_group_value_verified::Migration),
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use sea_orm_migration::prelude::*;

use crate::model::table::Asset;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_index(
Index::create()
.name("idx_asset_owner_supply")
.col(Asset::Owner)
.col(Asset::Supply)
.col(Asset::Burnt)
.col(Asset::OwnerType)
.table(Asset::Table)
.to_owned(),
)
.await?;

Ok(())
}

async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_index(
Index::drop()
.name("idx_asset_owner_supply")
.table(Asset::Table)
.to_owned(),
)
.await?;

Ok(())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use sea_orm_migration::prelude::*;

use crate::model::table::AssetGrouping;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_index(
Index::create()
.unique()
.name("asset_grouping_id_value_verified_unique")
.col(AssetGrouping::AssetId)
.col(AssetGrouping::GroupValue)
.col(AssetGrouping::Verified)
.table(AssetGrouping::Table)
.to_owned(),
)
.await?;
Ok(())
}

async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_index(
sea_query::Index::drop()
.name("asset_grouping_id_value_verified_unique")
.table(AssetGrouping::Table)
.to_owned(),
)
.await?;

Ok(())
}
}
Loading