Is there any way to compare an array in mongo aggregate? - javascript

This code does not match the bu.subUser with subUser and due to mismatch nothing is returned. How to achieve the output?
{
$match: {
subUser: {
$ne: blockedUsers.map((bu) => {
return bu.subUser;
}),
},
},
}

{ $match: { subUser: { $nin: blockedUsers.map((bu) => bu.subUser) } } }

Related

Mongo Update Query is not working properly

I have the data in one collection in the format given below
{
"tenantId":"Hello",
"timings":[{
"name":"Hi",
"category":"standard",
"pickAndPack":30,
"type":"pickup"
},
{
"name":"Hi",
"category":"premium",
"pickAndPack":30,
"type":"pickup"
}]
}
I want to update the data inside timings array.But its not working as expected.
Expected Output
{
"tenantId":"Hello",
"timings":[{
"name":"Hi",
"category":"standard",
"pickAndPack":30,
"type":"pickup"
},
{
"name":"Hello",
"category":"premium",
"pickAndPack":1200,
"type":"pickup"
}]
}
I have tried this query
let dataExists = [{
"name":"Hi",
"category":"standard",
"pickAndPack":30,
"type":"pickup"
},
{
"name":"Hello",
"category":"premium",
"pickAndPack":1200,
"type":"pickup"
}
masterdb.collection('corporate').update({ tenantId ,'timings.type': type}, { $set: { 'timings.$': dataExists } });```

Mongodb - Update property per object in array of object, Insert if doesn't exists

I wish to update a property per object in array of objects, but if some of the objects doesn't exists, insert the object instead.
Currently I used "upsert", which creates a new document when no document matches the query, unfortunately it is replacing a single item with my entire list.
Worth to mention that I am using mongoist to perform an async requests.
My code:
this.tokenArray = [
{ token: "654364543" },
{ token: "765478656" },
{ token: "876584432" },
{ token: "125452346" },
{ token: "874698557" },
{ token: "654364543" }
]
database.upsertDatebaseItem(this.tokenArray.map(x => { return x.token }), { valid : true }, 'Tokens');
async upsertDatebaseItem(itemKey, itemValue, collectionName) {
try {
await this.database[collectionName].update({ token : { $in: itemKey}}, { $set: itemValue }, {upsert : true} , {multi : true});
} catch (error) {
console.log(`An error occurred while attempting to update ${itemType} to the database: ${error}`);
return false;
}
}
Found the way to do it:
const bulkUpdate = this.tokenArray.map((x) => {
return {
"updateOne": {
"filter": { "token": x.token },
"update": { "$set": { "valid": true } },
"upsert": true
}
};
});
and:
this.database[collectionName].bulkWrite(bulkUpdate);
To upsert with mongoist, use the following:
var bulk = db.collection.initializeOrderedBulkOp()
for(var doc of docs) bulk.find( { _id: doc._id } ).upsert().updateOne(doc); // or use replaceOne()
await bulk.execute();
Converted to your case that would be
var bulk = db.collectionName.initializeOrderedBulkOp()
for(var tokenItem of tokenArray) bulk.find( { token : tokenItem.token } ).upsert().updateOne(tokenItem); // or use replaceOne()
await bulk.execute();

Aggregate is not a function - Mongoose Nodejs

Can somebody help me to fix this, here is my code for aggregate from mongoose:
export class GetVehiclesbyKotaCommandHandler {
constructor(namaKota) {
return new Promise((resolve, reject) => {
VehiclesDB.find().populate({
path: 'mitraId',
model: 'RentalDB',
select: 'namaKota'
}).aggregate([
{
$match : {
namaKota:namaKota
}
}
]).lean().then((dataVehicles)=>{
if(dataVehicles !== null){
resolve(dataVehicles);
} else {
reject (new NotFoundException('Couldn\'t find any Vehicles with namaKota' + namaKota));
}
}).catch((errDataVehicles)=>{
reject(new CanNotGetVehiclesException(errDataVehicles.message));
});
});
}}
And I get an error like this on the console:
TypeError: _VehiclesDB2.default.find(...).populate(...).aggregate is not a function
DONE, I Thanks for Hana :)
And i change my mitraId type ObjectId
mitraId : {
type: Schema.Types.ObjectId,
required: true
},
Try to avoid find, populate, lean function here and follow as like below
export class GetVehiclesbyKotaCommandHandler {
constructor(namaKota) {
return new Promise((resolve, reject) => {
VehiclesDB.aggregate([
{
$lookup: {
from: 'RentalDB',
localField: 'mitraId',
foreignField: '_id',
as: 'mitra'
}
}, {
$unwind: "$mitra"
}, {
$match: {
"mitra.namaKota": namaKota
}
}
]).then((dataVehicles)=>{
if(dataVehicles !== null){
resolve(dataVehicles);
} else {
reject (new NotFoundException('Couldn\'t find any Vehicles with namaKota' + namaKota));
}
}).catch((errDataVehicles)=>{
reject(new CanNotGetVehiclesException(errDataVehicles.message));
});
});
}}
You can use $lookup in the aggregation statement instead of using find, and populate here.
Like this:
VehiclesDB.aggregate([
{
$lookup: {
from: 'RentalDB',
localField: 'mitraId',
foreignField: '_id',
as: 'mitra'
}
}, {
$unwind: "$mitra"
}, {
$match: {
"mitra.namaKota": namaKota
}
}
])
I hope this helps.

Is MongoDB conditional aggregation available in Meteor 1.4.x ?

I'm trying to publish certain fields to a page based on a parameter of a document in a mongo collection. This is from the MongoDB manual: https://docs.mongodb.com/manual/reference/operator/aggregation/cond/
Does Meteor support conditional aggregation?
return Cases.find({
subscribers: { $in: [this.userId] }
}, {
fields: { $cond: [ { $eq: ['classified', true] } , Cases.privateFields, Cases.publicFields ] }
});
So, I realized I was approaching aggregates incorrectly. After doing some research on options to implement aggregation (meteorhacks) I decided to implement my own, which keeps the reactivity of the collection:
Extend Mongo.Collection
class CasesCollection extends Mongo.Collection {
conditionalFields(selector, modifier) {
let cond = modifier.fields[0],
pos = modifier.fields[1],
neg = modifier.fields[2];
if ( cond ) {
modifier = { fields: pos };
} else {
modifier = { fields: neg };
}
const cursor = this.find(selector, modifier);
return cursor;
}
}
Usage:
Meteor.publish('cases.dashboard', function casesDashboard() {
if (!this.userId) {
return this.ready();
}
return Cases.conditionalFields({
subscribers: { $in: [this.userId] }
}, {
fields: [ { $eq: ['classified', true] } , Cases.privateDashboardFields, Cases.dashboardFields ]
});
});

Node.js: How do I $pull from an array of $oid in Mongo/Mongoose?

I'm trying to remove an object from an array of $oid from within a single document with mongoose using update.
Here is a hypothetical schema based on the schema I'm using now:
var TestSchema = Schema({
name: { type: String },
otherRefs: [ {type: Schema.ObjectId, ref: 'OtherSchema' } ]
});
An example document would look like (note: these aren't actual ObjectIDs from my db - I just randomly typed them in to give an idea of what the document would look like - the documents in my actual db have valid $oid values:
{ "_id" : { "$oid" : "56da0b6326008d0c24a4f029" },
"name" : "name1",
"otherRefs" : [
{"$oid" : "56c340259402505c2720541b"},
{"$oid" : "56c340259402505c2720541e"},
{"$oid" : "56c340259402505c2720541f"},
{"$oid" : "56d758862494c411001ca603"}
]
}
Here is the query I'm trying to use:
TestSchema.update(
{ '_id': testResult._id },
{ $pull: { 'otherRefs': { $oid : mongoose.Schema.ObjectId( refResult._id ) } } },
false,
true,
function(err, success) {
if (err) {
res.json(err);
} else {
res.json('success', success);
}
}
)
Have also tried { $pull: { 'otherRefs': refResult._id } } with no success.
testResult._id and refResult._id are received from previous queries.
Been at this for a while now and can't seem to wrap my head around this problem. Hoping someone can help me figure out what I'm doing wrong.
Thanks!
EDIT:
Now using:
TestSchema.update(
{ '_id': testResult._id },
{ $pull: { 'otherRefs': refResult._id ) } },
function(err, success) {
if (err) {
console.log(err);
} else {
console.log('Success');
}
}
)
The query doesn't hang anymore and "Success" is getting logged but nothing is changed in the actual document in DB.

Categories