UnderscoreJS wont extend object - javascript

I am trying to merge 2 objects using underscore. The destination object is a mongoose model but I have applied lean() to it to make it return a javascript object rather than a mongo document.
model.find({}).lean().exec(function (error, object) {});
I then try extending using underscore
_.extend(object, source);
But it only returns the source object.
I have tried with simple objects to test and those worked fine, so I am assuming it has something to do with mongoose?
The simple objects that worked were:
{foo:'foo'},{bar:'bar'}
And the objects that I am trying to merge but haven't been able to are:
{
_id: 526540eaa77883d815000029,
name: 'House',
description: '',
type: 'residential',
cost: 100,
buildTime: 5,
resources: { produces: [], required: { wood: 5 } },
population: { provides: 10, required: 0 },
requires: [],
maxLevel: 5,
upgrades:
{ '2': { resourceMultiplier: 1.2, cost: 150, time: 5 },
'3': { resourceMultiplier: 1.5, cost: 200, time: 7 },
'4': { resourceMultiplier: 2, cost: 300, time: 10 },
'5': { resourceMultiplier: 2.5, cost: 500, time: 15 } },
scale: { x: 1, y: 1, z: 1 }
}
{
empireId: '52654578a4eff60000000001',
buildingId: '526540eaa77883d815000029',
level: 1,
isComplete: false,
isUpgrading: false,
gridId: '175|0|125',
started: 1382442513823,
_id: 526666113fccae68be000003,
__v: 0
}
Anyone come across this before or know where I am going wrong?

Well I am stupid. The source object was gotten from another mongoose query at the top of the file, this one was an instance of mongoose.Document and therefore couldn't be changed. I added lean() to it to make it return a javascript object and it's all working now.

Related

Trying to find alternative way to flatter the array of object in node

I am trying to bulk update using sequlize ORM but i have to run loop for that that i dont want to so how i can do without loop
i have list of object in team that i have to update in database
code is
bulkupdate_transaction = async(contest_team_data:any,flag:number):Promise<any> =>{
return new Promise(async (resolve, reject) =>{
try{
let data = []
for(let index = 0; index < contest_team_data.length;index++){
data.push({
team_id: contest_team_data[index].team_id,
team_name: contest_team_data[index].team_name,
user_id: contest_team_data[index].user_id,
contest_id: contest_team_data[index].contest_id,
contest_date: contest_team_data[index].contest_date,
selected_symbols: contest_team_data[index].selected_symbols,
status: contest_team_data[index].status,
fees_paid: contest_team_data[index].fees_paid,
po_id: contest_team_data[index].po_id,
points: contest_team_data[index].points,
bonus_deduction: contest_team_data[index].bonus_deduction,
cash_deduction: contest_team_data[index].cash_deduction,
winning_deduction: contest_team_data[index].winning_deduction,
winning_prize: contest_team_data[index].winning_prize,
win: (contest_team_data[index].winning_prize > 0) ? true : false,
rank: contest_team_data[index].rank,
createdat: contest_team_data[index].createdat,
updatedat: new Date()
})
}
await Teams.bulkCreate(data , {
updateOnDuplicate: ['points', 'rank','win','winning_prize']
});
resolve({success:true})
}catch(error){
console.log(error)
reject({success:false})
}
})
}
as you can see i have variable named contest_team_data that have value like that
[
teams {
dataValues: {
team_id: '4e1a430c-c697-457b-8b6f-b71e6990b6c3',
po_id: 'ff1bdd59-272f-4c18-97bf-b54dbd8d0020',
user_id: '15218145-d032-4971-b3f9-d2cb2a09adc9',
selected_symbols: [Array],
team_name: 'test 9',
contest_id: '5c8fbd6f-fa57-40f8-97e6-ccc47f537764',
contest_date: '2022-07-25',
status: 'Live',
fees_paid: 50,
bonus_deduction: 5,
winning_deduction: 0,
cash_deduction: 45,
createdat: 2022-07-25T05:38:40.824Z,
purchaseOrder: [purchase_orders],
points: '-137472',
rank: 14
}
},
teams {
dataValues: {
team_id: '5f73f75b-51c7-46c5-bdf5-0c61d25471f7',
po_id: 'ff1bdd59-272f-4c18-97bf-b54dbd8d0020',
user_id: '15218145-d032-4971-b3f9-d2cb2a09adc9',
selected_symbols: [Array],
team_name: 'test 14',
contest_id: '5c8fbd6f-fa57-40f8-97e6-ccc47f537764',
contest_date: '2022-07-25',
status: 'Live',
fees_paid: 50,
bonus_deduction: 5,
winning_deduction: 0,
cash_deduction: 45,
createdat: 2022-08-26T05:38:40.824Z,
purchaseOrder: [purchase_orders],
points: '-130864',
rank: 13
}
}
]
when i trying to pass contest_team_data in sequlize for bulk update getting error for getting null but i have value in object
now please any one can help to how to solve this.
Unfortunately you should use a for loop to update all records based on a given array because Sequelize does not support such feature (basically most if not every DBMS do not support multi-record update for each record individually).

Recursive Way to Find & Assign Correct Value

I have a situation where I need to find a value from an array of objects, depending on the object that has the highest value for a property named sequence. When I find the object with the highest numeric value for sequence then I want to assign the value of variable to the value of another property on that same object. I could do this with a long loop with numerous conditionals, but I'm wondering if there's a simpler way to do this via some kind of recursive process.
My data look like this:
let endDate;
let data = [
{
clientId: 912,
coverage: {
start: '2021-07-30',
finish: '2021-12-31',
agent: {
name: 'Second',
sequence: 2
},
}
},
{
clientId: 912,
coverage: {
start: '2021-08-01',
finish: '2021-12-20',
agent: {
name: 'First',
sequence: 1
},
}
},
{
clientId: 912,
coverage: {
start: '2021-09-13',
finish: '2021-12-25',
agent: {
name: 'Third',
sequence: 3
},
}
},
];
What I want do do is set a variable named subscriptionEndDate to the value of finish on whatever object from the above array that has the highest numeric value for coverage.agent.sequence.
The result for endDate for the above data should be '2021-12-25'.
You don't need recursion as you'll only need to iterate over the array and get the client with max sequence, you can use Array#reduce as follows:
const data = [
{ clientId: 912, coverage: { id: 59307, start: '2021-07-30', finish: '2021-12-31', agent: { name: 'Third', sequence: 2 } } },
{ clientId: 912, coverage: { id: 59307, start: '2021-08-01', finish: '2021-12-20', agent: { name: 'First', sequence: 1 } } },
{ clientId: 912, coverage: { start: '2021-09-13', finish: '2021-12-25', agent: { name: 'Second', sequence: 3 } } }
];
const clientWithHighestSequence = data.reduce((maxSeqClient, client) =>
client.coverage.agent.sequence > (maxSeqClient?.coverage.agent.sequence ?? 0)
? client
: maxSeqClient
, null);
console.log(clientWithHighestSequence);

How to keep null values at the end of sorting in Mongoose? [duplicate]

This question already has answers here:
How can I sort into that nulls are last ordered in mongodb?
(2 answers)
Closed 4 years ago.
I am querying a collection and sorting results based on a property. Some documents don't the that property value yet i.e. null. I want to keep the documents with null values at the end of the results after sorting and limiting (asc or desc). Is there a simple way in Mongoose to do that using a single query?
If not, how can I use two queries separately since I have to limit the results as well for pagination?
var dealSchema = new Schema({
// For Presentation Purposes Only
dealId: { type: Number, index: true, unique: true },
// BRAND Info
brand: { type: ObjectId, ref: 'brand', index: true },
brandUser: { type: ObjectId, ref: 'user', index: true, required: true },
campaign: { type: ObjectId, ref: 'campaign', index: true },
metrics: {
totalCost: Number,
totalValue: Number,
roi: { type: Number, index: true },
cpe: { type: Number, index: true }
}
})
I want to sort based on 'metrics.cpe' in ascending order, but want null or 0 values to be at the end of the list. Example:
[0.1, 0.4, 0.7, 1.5, 2.5, 0, 0, null, null]
Sample document
{
"_id": "590cdf29c102ae31208fa43a",
"campaign": "587e6a880c844c6c2ea01563",
"brand": "5a4cff5f8eaa1c26ca194acc",
"brandUser": "57fd30cf0df04f1100153e07",
"metrics": {
"roi": 0,
"cpe": 0,
"totalValue": 0,
"totalCost": 6000
}
}
Am not sure about the solution am about to say. I cant test this out as I dont have a mongo db set right now, but I think that you can use <collection>.aggregate along with $project and $sort to achieve this.
Sample code:
db.inventory.aggregate(
[
{
$project: {
item: 1,
description: { $ifNull: [ "$amount", -1*(<mimimum value>)* ] }
}
},
{
$sort : {
amount : (-1 or 1 depending on the order you want)
}
}
]
)
Hope this helps !!

Issue finding mongoose ObjectID in array of strings representing ObjectIDs

I need to find the index of the mongoose objectID in an array like this:
[ { _id: 58676b0a27b3782b92066ab6, score: 0 },
{ _id: 58676aca27b3782b92066ab4, score: 3 },
{ _id: 58676aef27b3782b92066ab5, score: 0 }]
The model I am using to compare is a mongoose schema with the following data:
{_id: 5868d41d27b3782b92066ac5,
updatedAt: 2017-01-01T21:38:30.070Z,
createdAt: 2017-01-01T10:04:13.413Z,
recurrence: 'once only',
end: 2017-01-02T00:00:00.000Z,
title: 'Go to bed without fuss / coming down',
_user: 58676aca27b3782b92066ab4,
__v: 0,
includeInCalc: true,
result: { money: 0, points: 4 },
active: false,
pocketmoney: 0,
goals: [],
pointsawarded: { poorly: 2, ok: 3, well: 4 },
blankUser: false }
I am trying to find the index of the model._user in the array above using the following:
var isIndex = individualScores.map(function(is) {return is._id; }).indexOf(taskList[i]._user);
Where individualScores is the original array and taskList[i] is the task model. However, this always returns -1. It never finds the correct _id in the array.
I guess your problem is related to how _id are returned by your query
If you get _id as String, your code should work, check the snippet below
But if instead, you get ObjectsIds, you have to cast them to String first
var individualScores = [
{ _id: "58676b0a27b3782b92066ab6", score: 0 },
{ _id: "58676aca27b3782b92066ab4", score: 3 },
{ _id: "58676aef27b3782b92066ab5", score: 0 }
]
var task = {
_id: "5868d41d27b3782b92066ac5",
updatedAt: new Date("2017-01-01T21:38:30.070Z"),
createdAt: new Date("2017-01-01T10:04:13.413Z"),
recurrence: 'once only',
end: new Date("2017-01-02T00:00:00.000Z"),
title: 'Go to bed without fuss / coming down',
_user: "58676aca27b3782b92066ab4",
__v: 0,
includeInCalc: true,
result: { money: 0, points: 4 },
active: false,
pocketmoney: 0,
goals: [],
pointsawarded: { poorly: 2, ok: 3, well: 4 },
blankUser: false
}
var isIndex = individualScores.map(
function(is) {
return is._id;
})
.indexOf(task._user);
console.log(isIndex)
I think your process should working well that you are using just only need to convert 'objectID' to String to compare. Convert using .toString() for both of _id and _user.
like bellow:
var isIndex = individualScores.map(function(is) {
return is._id.toString();
}).indexOf(taskList[i]._user.toString());

mongodb search query - returns all results (non matching ones too)

This is a sample from MEAN stack website,
I require the query to return parameters that match ' exactly ' with the input.
Please view the image attached to understand the issue better.
Search Query Function
Any hint on this issue ? (I'm a beginner so please elaborate a little)
-TIA :)
Input for the search from the browser
{ body: { hp: 1, length: 1, diameter: 1, voltage: 1 } }
// mongo schema
var CableSchema = new schema({
body : {
"hp": {
type: Number
},
"length": {
type: Number
},
"diameter": {
type: Number
},
"voltage": {
type: Number
},
"cost": {
type: Number
},
"type": {
type: String,
default: "Cable"
}
}
});
-----------------------------------------------------------
// Result from Search Query obtained in console
[ { body:
{ type: 'Cable',
cost: 1,
voltage: 1,
diameter: 1,
length: 1,
hp: 1 },
__v: 0,
_id: 5820246086d42a3c269ad9f2 },
{ body:
{ type: 'Cable',
cost: 2,
voltage: 2,
diameter: 2,
length: 2,
hp: 2 },
__v: 0,
_id: 5820249086d42a3c269ad9f3 } ]`
The keys 'hp','length' etc are inside the body object of cable schema. So to refer 'hp' use 'body.hp' in query
Change your query to
var query = Cable.find({'body.hp' : parseInt(reqHp) , 'body.length' : parseInt(reqLen),
'body.diameter' : parseInt(reqDia) ,'body.voltage' : parseInt(reqVol)})
The confusion was with assignment - 1body was from req body and the other one was from '2body' schema
I needed to use 1body.2body to reach inside for the data.
var reqHP = req.body.body.hp;
var reqLen = req.body.body.length;
var reqDia = req.body.body.diameter;
var reqVol = req.body.body.voltage;
var reqCost = req.body.body.cost;

Categories