updateMany mongoose with multiple condition - javascript

I have two documents as in db bookingDetails" as:
{
"_id":ObjectId("12jj21jan21jdo3kan2idm11"),
"book_status":"BOOKED",
"reservation":false,
}
{
"_id":ObjectId("12jj21jan21jdo3kan2idm11"),
"book_status":"ACCEPTED",
"reservation":true,
}
update both of the document with multiple queries.
I am trying as,
bookingDetails.updateMany(
{
"book_status":"ACCEPTED",
},
{
$set:{
"book_status":"DONE"
}
}
)
bookingDetails.updateMany(
{
"book_status":"BOOKED",
},
{
$set:{
"book_status":"DONE"
}
}
)
But this method is repetitive which increases load on db. Is there any way that it can be optimized?
Please let me know if anyone needs any further information.

You can use an $or like this:
bookingDetails.updateMany({
"$or": [
{
"book_status": "ACCEPTED"
},
{
"book_status": "BOOKED"
}
]
},
{
"$set": {
"book_status": "DONE"
}
})
Example here

Related

Update mongo collection with values from a javascript map

I have a collection that looks like this
[
{
"project":"example1",
"stores":[
{
"id":"10"
"name":"aa",
"members":2
}
]
},
{
"project":"example2",
"stores":[
{
"id":"14"
"name":"bb",
"members":13
},
{
"id":"15"
"name":"cc",
"members":9
}
]
}
]
I would like to update the field members of the stores array taking getting the new values from a Map like for example this one
0:{"10" => 201}
1:{"15" => 179}
The expected result is:
[
{
"_id":"61",
"stores":[
{
"id":"10"
"name":"aa",
"members":201
}
]
},
{
"_id":"62",
"stores":[
{
"id":"14"
"name":"bb",
"members":13
},
{
"id":"15"
"name":"cc",
"members":179
}
]
}
]
What are the options to achieve this using javascript/typescript?
In the end, I resolved by updating the original database entity object with the values in the map, then I have generated a bulk query.
for (let p of projects) {
for(let s of p.stores) {
if(storeUserCount.has(s.id)){
s.members = storeUserCount.get(s.id);
}
};
bulkQueryList.push({
updateOne: {
"filter": { "_id": p._id },
"update": { "$set": {"stores": p.stores} }
}});
};
await myMongooseProjectEntity.bulkWrite(bulkQueryList);
You can use update() function of Mongoes model to update your expected document.
Try following one:
const keyValArray= [{"10": 201},{"15":"179"}];
db.collectionName.update({_id: givenId},
{ $push: { "stores": {$each: keyValArray} }},
function(err, result) {
if(err) {
// return error
}
//return success
}
});

How to add a MongoDB match argument if it comes from frontend and not add any argument if it doesn't?

I am creating an aggregation in MongoDB using NodeJS. When the resolver function is called with an argument, I want it to be added to MongoDB match function and if it doesn't exist, then there will be no addition. The problem I am facing is that if there is no addition, no results are coming and if there is addition then the query is not coming properly. It is coming like this: phaseMatch = 'phase': { $in: CAT,MOD }. how do I make it come like phaseMatch = 'phase': { $in: ['CAT','MOD'] }? Is there any way to do this conditional only in the MongoDB aggregation and not use any JS?
async WeeklyTable(_, { batchSize, phase }) {
let res = [];
let phaseMatch = "";
if(phase) phaseMatch = "'phase': { $in: " + phase + " }";
return await collection.aggregate([{
$match: {
"segment": {
$exists: true,
$ne: null
},
phaseMatch
}
}];
}
There are many ways to dynamically build a query condition, here is a quick example:
async WeeklyTable(_, { batchSize, phase }) {
const res = [];
const matchCond = {
"segment": {
$exists: true,
$ne: null
},
}
if(phase) {
matchCond.phase = {$in: phase}
};
return await collection.aggregate([{
$match: matchCond
}];
}
Not sure exactly what you're trying to do with creating it as a string, the Mongo driver doesn't parse string arguments as query conditions.
EDIT
Without any javascript you could do:
db.collection.aggregate([
{
$match: {
"segment": {
$exists: true,
$ne: null
},
$expr: {
"$setIsSubset": [
[
"$phase"
],
{
$ifNull: [
phase,
[
"$phase"
]
]
}
]
}
}
}
])

Logic App/JavaScript - Remove Matching Values

I have two data sources. Data Source 1 is basically a list of Projects and Users assigned to those Projects. Data Source 2 is a list of Users that I want to remove from the Projects in Data Source 1.
Data Source 1:
[
{
"db1Project":[
{
"projectCode":"1",
"assignment":{
"db1User":[
{
"assignee":"wantzc"
},
{
"assignee":"michelles"
}
]
}
},
{
"projectCode":"2",
"assignment":{
"db1User":[
{
"assignee":"stallinga"
},
{
"assignee":"domanl"
},
{
"assignee":"brantleyd"
}
]
}
},
{
"projectCode":"3",
"assignment":{
"db1User":[
{
"assignee":"cinnamonk"
}
]
}
}
]
}
]
I want to match "assignee" from Data Source 1 with "sponsor" in Data Source 2.
Data Source 2:
[
{
"db2Users":[
{
"sponsor":"wantzc"
},
{
"sponsor":"patem"
},
{
"sponsor":"stallinga"
},
{
"sponsor":"oliviaa"
},
{
"sponsor":"brantleyd"
}
]
}
]
Then remove non-matching "assignee" and generate below output:
Desired Output:
[
{
"db1Project":[
{
"projectCode":"1",
"assignment":{
"db1User":[
{
"assignee":"wantzc"
}
]
}
},
{
"projectCode":"2",
"assignment":{
"db1User":[
{
"assignee":"stallinga"
},
{
"assignee":"brantleyd"
}
]
}
}
]
}
]
Can this be done using Logic App only? If not, how to do this using JavaScript?
This is a little bit of a verbose way to do it in Javascript, but the idea is relatively simple:
Create a map of the users you're looking for so you have an O(1) lookup instead of O(n) lookup each time
Filter the users list for each project to only contain users found in the db2Users list
Add the project to the new results set if any db1Users remain after step 2
This will take 1 pass through your original array, so it's an efficient, yet simple algorithm to do what you're trying to do.
let data = [{"projectCode":"1","assignment":{"db1User":[{"assignee":"wantzc"},{"assignee":"michelles"}]}},{"projectCode":"2","assignment":{"db1User":[{"assignee":"stallinga"},{"assignee":"domanl"},{"assignee":"brantleyd"}]}},{"projectCode":"3","assignment":{"db1User":[{"assignee":"cinnamonk"}]}}];
let db2Users = [{"sponsor":"wantzc"}, {"sponsor":"patem"}, {"sponsor":"stallinga"}, {"sponsor":"oliviaa"}, {"sponsor":"brantleyd"}];
let db2UsersMap = db2Users.reduce((res, curr) => {
res[curr.sponsor] = true;
return res;
}, {});
let filteredProjects = data.reduce((res, project) => {
let currProjUsers = project.assignment.db1User;
project.assignment.db1User = currProjUsers.filter((user) => db2UsersMap[user.assignee]);
if (project.assignment.db1User.length > 0) { res.push(project); }
return res;
}, []);
console.log(filteredProjects);

How would I replace the key options inside an object with a spread inside of a map function in react

I have the following code which is changing the value of the options key in the inputType multipleChoice object the main object is called cards and I need to set the state to the newTasksIdsArray
I want the multipleChoice.options to have the newArray values so I can setthe state to them
Update: more info
I guess what I am trying to say is I need the a variable to setlocalstroage eventually to be the entireObject with the optiosn array replaced with whatever would be in newTasksIdsArray which i have generated, just not included because It't probably not neccesary
Thanks!
I need my final result to be
[
{
"inputType":"multipleChoice",
"uniId":"bzR7bpwzjMxcBEdSF",
"label":"Preferred Method of Contact",
"value":"2813348004",
"multipleChoice":{
"options":NEW ARRAY GOES HERE
}
},
...
KEEP REST OF OBJECT
]
let test = [];
cards.map((card) => {
if (card.inputType === "multipleChoice") {
//console.log(card);
card.multipleChoice.options = newTasksIdsArray;
test.push(...cards);
}
});
console.log(test);
setCards(test)
//update localstorage with test as well
This is the cards object
[
{
"inputType":"multipleChoice",
"uniId":"bzR7bpwzjMxcBEdSF",
"label":"Preferred Method of Contact",
"value":"2813348004",
"multipleChoice":{
"options":[
{
"uniId":"gJ8N6sAJrZZvCcPkp",
"label":"Cell Phone",
"checked":false
},
{
"uniId":"Ha9rmssmRkGzpRTn7",
"label":"Email",
"checked":true
}
]
}
},
{
"inputType":"shortText",
"uniId":"AkvioWe6D2ahgDCbW",
"label":"First Name:",
"value":"Kanye",
"multipleChoice":{
}
},
{
"inputType":"phoneNumber",
"uniId":"xwbBBnT2D69QJHHuL",
"label":"Cell Phone Number",
"value":"2813348004",
"multipleChoice":{
}
},
{
"inputType":"email",
"uniId":"62fDs7JtTF4MxMvww",
"label":"Work Email",
"value":"kanye#usa.gov",
"multipleChoice":{
}
},
{
"inputType":"address",
"uniId":"pKAwHmRJKCcKMz8LN",
"label":"Home Address",
"value":"123 White House Avenue",
"multipleChoice":{
}
},
{
"inputType":"dropDown",
"uniId":"K3o689k8G2ZrWEfQc",
"label":"How did you find us?",
"value":"2813348004",
"dropDown":{
"uniId":"3r9gzPXXjidq9p4fw",
"options":[
{
"uniId":"7hGYT4jv89WxFveaj",
"label":"Google"
},
{
"uniId":"J2K2W6P4BR7ZEGEao",
"label":"Referral"
}
]
},
"multipleChoice":{
}
}
]
I guess the cards state was already updated by the reaasignment of the value in the map function so this just works fine to store to localstorage
cards.map((card) => {
if (card.inputType === "multipleChoice") {
card.multipleChoice.options = newTasksIdsArray;
}
});
window.localStorage.setItem("inputs", JSON.stringify(cards)

Compare 2 values from same doc in mongo

I want to compare 2 values in same doc id
For example
{
"_id" : ObjectId("5f180441ad1cd40008dc6a5a"),
"fcount" : 5,
"key" : "27b6e581-796c-4f3a-882b-0e0c2a0a8a64",
"student_id" : "5f0ffbcdd67d70c1a3b143aa",
"__v" : 0,
"dcount" : 5
}
I have this doc, Now If I want to check fcount and dcount is same then return true. OR false
How can I do this with mongoose query?
update:
const result = await execute_reports_model.find({ _id: _id}).lean().cursor({batchSize: 10}).eachAsync(async ({fcount, dcount}) => {
if (fcount === dcount) {
// true Logic
} else {
// false logic
}
}, { parallel: 10})
So here I will be passing the ID in find. and then compare values that I found from that ID. values are fcount and dcount
Using Mongoose's Model.aggregate you can compare a document's two fields and return a boolean:
const result = await model.aggregate([
{ $match: { _id: id } },
{ $project: { _id: 0, isMatch: { $eq: [ "$fcount", "$dcount" ] } } }
])
result value: { "isMatch" : true }
This precursor code will help you to solve your problem. It will allow you to find the necessary documents and then deal with all true and false cases.
{batchSize: 10} and {parallel:10} will help you to do your task at parallel. You could easily modify them.
Don't forget to add callback or handle all cases somehow, as you need it to.
await collection_name.find({ your_query: here}).lean().cursor({batchSize: 10}).eachAsync(async ({fcount, dcount}) => {
if (fcount === dcount) {
//true case
} else {
//false case
}
}, { parallel: 10})

Categories

Resources