Skip to content

Commit

Permalink
feat: modify query
Browse files Browse the repository at this point in the history
  • Loading branch information
ayushtom committed Jan 11, 2024
1 parent ab6b2cd commit 859cfeb
Showing 1 changed file with 119 additions and 144 deletions.
263 changes: 119 additions & 144 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use mongodb::{
bson::doc, options::UpdateOptions, results::UpdateResult, Collection, Cursor, Database,
IndexModel,
};
use rand::distributions::{Distribution, Uniform};
use starknet::signers::Signer;
use starknet::{
core::{
Expand Down Expand Up @@ -497,170 +496,146 @@ pub async fn fetch_and_update_boosts_winner(
"expiry":{
"$lt": Utc::now().timestamp_millis()
},
// "winner": {
// "$eq": null,
// },
"winner": {
"$eq": null,
},
}
}];
match boost_collection.aggregate(pipeline, None).await {
Ok(mut cursor) => {
while let Some(doc) = cursor.try_next().await.unwrap() {
let mut num_of_winners = doc.get("num_of_winners").unwrap().as_i32().unwrap();
// use this variable to add some extra winners so that we have some extra winners incase anyone user repeats
let extra_winners = 10;
let num_of_winners = doc.get("num_of_winners").unwrap().as_i32().unwrap();
match doc.get("quests") {
Some(quests_res) => {
let quests = quests_res.as_array().unwrap();
let mut address_list: Vec<FieldElement> = Vec::new();
for quest in quests {
let get_users_per_quest_pipeline = vec![
doc! {
"$lookup": doc! {
"from": "tasks",
"localField": "task_id",
"foreignField": "id",
"as": "associated_tasks"
}
},
doc! {
"$match": doc! {
"$expr": doc! {
"$eq": [
doc! {
"$first": "$associated_tasks.quest_id"
},
quest
]
}
}
},
doc! {
"$group": doc! {
"_id": "$address",
"tasks_list": doc! {
"$push": doc! {
"$arrayElemAt": [
"$associated_tasks",
0
]
}
}
}
},
doc! {
"$unwind": "$tasks_list"
},
doc! {
"$group": doc! {
"_id": doc! {
"address": "$_id",
"quest_id": "$tasks_list.quest_id"
},
"tasks_array": doc! {
"$push": "$tasks_list"
}
}
},
doc! {
"$project": doc! {
"_id": 0,
"address": "$_id.address",
"quest_id": "$_id.quest_id",
"tasks_array": 1
let mut address_list: Vec<String> = Vec::new();
let get_users_per_quest_pipeline = vec![
doc! {
"$lookup": doc! {
"from": "tasks",
"localField": "task_id",
"foreignField": "id",
"as": "associated_tasks"
}
},
doc! {
"$unwind": doc! {
"path": "$associated_tasks"
}
},
doc! {
"$match": doc! {
"$expr": doc! {
"$in": [
"$associated_tasks.quest_id",
quests
]
}
},
doc! {
"$lookup": doc! {
"from": "tasks",
"localField": "quest_id",
"foreignField": "quest_id",
"as": "associatedTasks"
}
},
doc! {
"$group": doc! {
"_id": "$address",
"tasks_list": doc! {
"$push": "$associated_tasks"
}
},
doc! {
"$match": doc! {
"$expr": doc! {
"$eq": [
doc! {
"$size": "$tasks_array"
},
doc! {
"$size": "$associatedTasks"
}
]
}
}
},
doc! {
"$unwind": "$tasks_list"
},
doc! {
"$group": doc! {
"_id": doc! {
"address": "$_id",
"quest_id": "$tasks_list.quest_id"
},
"tasks_array": doc! {
"$push": "$tasks_list"
}
},
doc! {
"$project": doc! {
"address": "$address"
}
},
doc! {
"$project": doc! {
"_id": 0,
"address": "$_id.address",
"quest_id": "$_id.quest_id",
"tasks_array": 1
}
},
doc! {
"$lookup": doc! {
"from": "tasks",
"localField": "quest_id",
"foreignField": "quest_id",
"as": "associatedTasks"
}
},
doc! {
"$match": doc! {
"$expr": doc! {
"$eq": [
doc! {
"$size": "$tasks_array"
},
doc! {
"$size": "$associatedTasks"
}
]
}
},
doc! {
"$sample":{
"size":num_of_winners+extra_winners
}
},
doc! {
"$project": doc! {
"address": "$address"
}
},
doc! {
"$group": doc! {
"_id": "$address",
"weight": doc! {
"$sum": 1
}
},
];
match completed_tasks_collection
.aggregate(get_users_per_quest_pipeline, None)
.await
{
Ok(mut cursor) => {
while let Some(doc) = cursor.try_next().await.unwrap() {
let address =
doc.get("address").unwrap().as_str().unwrap();
let formatted_address =
FieldElement::from_str(address).unwrap();
address_list.push(formatted_address);
}
},
doc! {
"$addFields": doc! {
"entropy": doc! {
"$divide": [
doc! {
"$rand": doc! {}
},
"$weight"
]
}
}
Err(_err) => {}
}
}

// skip if no user has completed quests
if address_list.len() == 0 {
continue;
}
let mut random_index;
let mut winner_array: Vec<String> = Vec::new();

// if length of address list is 1 then select the only user
if address_list.len() == 1 {
let winner = &address_list[0].to_string();
let formatted_winner = FieldElement::from_str(winner).unwrap();
winner_array.push(to_hex(formatted_winner));
}
// else select random users
else {
let mut current_winner_index = 0;
// handle case when number of winners is greater than number of users then assign all users as winners
if address_list.len() < num_of_winners as usize {
num_of_winners = address_list.len() as i32;
}
let mut iter_index = 0;
loop {
let mut rng = rand::thread_rng();

let die = Uniform::new(0, address_list.len());
random_index = die.sample(&mut rng);

let winner = &address_list[random_index].to_string();
let formatted_winner = FieldElement::from_str(winner).unwrap();
if !winner_array.contains(&to_hex(formatted_winner)) {
winner_array.push(to_hex(formatted_winner));
current_winner_index += 1;
},
doc! {
"$sort": doc! {
"entropy": -1
}
iter_index += 1;
if current_winner_index == (num_of_winners) as usize || iter_index == address_list.len() {
break;
},
doc! {
"$limit": (num_of_winners) as i64
},
];
match completed_tasks_collection
.aggregate(get_users_per_quest_pipeline, None)
.await
{
Ok(mut cursor) => {
while let Some(doc) = cursor.try_next().await.unwrap() {
let address = doc.get("_id").unwrap().as_str().unwrap();
let formatted_address =
FieldElement::from_str(address).unwrap();
address_list.push(to_hex(formatted_address));
}
}
Err(_err) => {}
}

let filter = doc! { "id": doc.get("id").unwrap().as_i32().unwrap() };
let update = doc! { "$set": { "winner": winner_array } };
let update = doc! { "$set": { "winner": address_list } };
let options = UpdateOptions::builder().upsert(true).build();
boost_collection
.update_one(filter, update, options)
Expand Down

0 comments on commit 859cfeb

Please sign in to comment.