Populate with condition return null in mongoose - javascript

I need to get all production results where machine name is 'CircuitPrinter'
ProductionResult schema:
import { Schema, model } from 'mongoose';
const schemaOptions = {
timestamps: { createdAt: 'created_at', updatedAt: false },
};
const productionResultSchema = new Schema({
machineId: { type: Schema.Types.ObjectId, ref: 'Machine' },
operatorId: { type: Schema.Types.ObjectId, ref: 'Operator' },
orderId: { type: Schema.Types.ObjectId, ref: 'Order' },
elementId: { type: Schema.Types.ObjectId, ref: 'Element' },
}, schemaOptions);
export default model('ProductionResult', productionResultSchema);
Machine Schema
import { Schema, model } from 'mongoose';
const schemaOptions = {
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' },
};
const machineSchema = new Schema({
name: { type: String },
status: { type: String },
date: { type: Date },
amount: { type: Number },
}, schemaOptions);
export default model('Machine', machineSchema);
Service function:
async getBar() {
return ProductionResult.find()
.populate({
path: 'machineId',
match: { name: 'CircuitPrinter' },
});
}
But in response I get machineId with null
Without match I get correct response with full machine data. What's wrong with my condition. Machine with CircuitPrinter name exist in database.
{
"_id": "608c532e4051960ef05176f4",
"machineId": null,
"elementId": "608c4e914051960ef05176cc",
"operatorId": "608c4e914051960ef05176d2",
"orderId": "608c4e914051960ef05176eb",
"created_at": "2021-04-30T18:57:50.771Z",
"__v": 0
}
Edited:
Sample data Machines document:
{
"_id": {
"$oid": "608c4e914051960ef05176ed"
},
"name": "CircuitPrinter",
"status": "Running",
"__v": 0,
"created_at": {
"$date": "2021-04-30T18:38:09.326Z"
},
"updated_at": {
"$date": "2021-04-30T18:38:09.326Z"
}
}
Sample data ProductionResult document:
{
"_id": {
"$oid": "608c532e4051960ef05176f4"
},
"machineId": {
"$oid": "608c4e914051960ef05176f0"
},
"elementId": {
"$oid": "608c4e914051960ef05176cc"
},
"operatorId": {
"$oid": "608c4e914051960ef05176d2"
},
"orderId": {
"$oid": "608c4e914051960ef05176eb"
},
"created_at": {
"$date": "2021-04-30T18:57:50.771Z"
},
"__v": 0
}

Related

Aggregate data from nested array

I need help with the aggregate framework.
I have a model (currencies field can contain more than one object):
const schema = new mongoose.Schema({
country: { type: String },
code: { type: String },
region: [{
name: { type: String },
path: { type: Array },
city: [{
name: { type: String },
path: { type: Array },
latitude: { type: String },
longitude: { type: String },
}],
}],
currencies: [{
code: { type: String },
name: { type: String },
symbol: { type: String },
}],
})
And I need to receive all currencies without duplicates.
Received data can view like this:
[
{ code: 'string', name: 'sting', symbol: 'string' },
{ code: 'string', name: 'sting', symbol: 'string' },
...
]
// or like this:
[
currencies: [
{ code: 'string', name: 'sting', symbol: 'string' },
{ code: 'string', name: 'sting', symbol: 'string' },
...
]
]
I try to create a query
Geo.aggregate([
{
$group: {
_id: null,
currencies: { $addToSet: '$currencies' },
},
},
])
but receive this data with duplicates and it has many nested arrays:
[
{
"_id": null,
"currencies": [
[
{
"_id": "5cd9486248989616a411fac5",
"code": "JPY",
"name": "Japanese yen",
"symbol": "¥"
}
],
[
{
"_id": "5cd9491a48989616a411fb47",
"code": "TRY",
"name": "Turkish lira",
"symbol": null
}
],
I try this query:
Geo.aggregate([
{
$addFields: {
code: '$currencies.code',
name: '$currencies.name',
symbol: '$currencies.symbol',
},
},
])
But I receive error "TypeError: item is not iterable".
I need little help )
Db data views like this:
{
"_id": {
"$oid": "5c3334a8871695568817eadf"
},
"country": "Singapore",
"code": "sg",
"region": [
{
"path": [
"Singapore"
],
"_id": {
"$oid": "5c3366c63d92ac6e531e05c0"
},
"city": [],
"name": "Central Singapore Community Development Council"
},
....
],
"__v": 0,
"currencies": [
{
"_id": {
"$oid": "5cd948ec48989616a411fb28"
},
"code": "BND",
"name": "Brunei dollar",
"symbol": "$"
},
{
"_id": {
"$oid": "5cd948ec48989616a411fb27"
},
"code": "SGD",
"name": "Singapore dollar",
"symbol": "$"
}
]
}
In aggregate pipeline first you need to unwind the currencies array and then group them by condition to get desired result.
Geo.aggregate([
{
$unwind: '$currencies'
},
{
$group: {
_id: null,
currencies: { $addToSet: '$currencies' },
},
},
])
For more information you can look into documentation here
db.temp.aggregate([
{$project : {currencies : 1}},
{$unwind: "$currencies"},
{
$addFields: {
currencyHash: {
$concat : ['$currencies.code', "--", "$currencies.name", "--", "$currencies.symbol"]
}
}
},
{
$group: {
_id: "$currencyHash",
currency : {
$first : "$currencies"
}
}
},
{
$project: {
code : "$currency.code",
name : "$currency.name",
symbol : "$currency.symbol"
}
},
{
$project: {
_id : 0,
currency : 0
}
}
]).pretty()

Creating a new table in mongoose based on object IDs

Hello the title of this question is very poorly worded however i will better explain the issue.
I have a document called 'buildings', and I also have two documents called 'rooms' and 'logins'. In both rooms and logins, they have an embedded document of building as follows:
Room Schema:
const roomSchema = new mongoose.Schema({
name: {
type: String,
required: true,
minlength: 1,
maxlength: 255
},
building: {
type: new mongoose.Schema({
name: {
type: String,
required: true,
minlength: 1,
maxlength: 255
}
}),
required: true
}
});
Logins Schema:
const loginSchema = new mongoose.Schema({
user: {
type: new mongoose.Schema({
email: {
type: String,
required: true
},
isVisitor: {
type: Boolean,
required: true
}
})
},
dateIn: {
type: Date,
required: true,
default: Date.now()
},
dateOut: {
type: Date
},
building: {
type: new mongoose.Schema({
name: {
type: String,
required: true
}
})
}
});
And the building schema is as follows:
const Building = mongoose.model(
"Building",
new mongoose.Schema({
name: {
type: String,
required: true,
minlength: 1,
maxlength: 255
},
address: {
type: String,
required: true,
minlength: 1,
maxlength: 255
},
postcode: {
type: String,
required: true,
minlength: 6,
maxlength: 8
},
organisation: {
type: new mongoose.Schema({
name: {
type: String,
required: true
}
})
}
})
);
Here is some examples of documents from each schema:
Building:
{
"_id": "5c79a31ed2016312ecd27c46",
"name": "TusPark",
"site": {
"_id": "5c79a243d2016312ecd27c45",
"name": "TusPark Newcastle"
},
"__v": 0
},
Rooms:
{
"_id": "5c7fa01abdd6233d6fdbc917",
"name": "E101",
"building": {
"_id": "5c79a31ed2016312ecd27c46",
"name": "TusPark"
},
"__v": 0
},
Logins:
{
"dateIn": "2019-03-21T13:13:23.069Z",
"_id": "5c938e151bd7a02d479893bd",
"user": {
"_id": "5c925378e88bb72764283108",
"email": "jack1#gmail.com",
"isVisitor": true
},
"building": {
"_id": "5c79a31ed2016312ecd27c46",
"name": "TusPark"
},
"__v": 0
}
I am trying to send a document to the client which contains the building details, with the rooms and logins embedded as attributes for the relevant building. The code I currently have written for this is below:
router.get("/all", async (req, res) => {
const buildings = await Building.find();
const rooms = await Room.find({
building_id: buildings._id
});
const logins = await Login.find({
building_id: buildings._id
});
const building_rooms = await Building.aggregate([
{
$lookup: {
from: "rooms",
localField: "building_id",
foreignField: "building_id",
as: "building_rooms"
}
},
{
$lookup: {
from: "logins",
localField: "building_id",
foreignField: "building_id",
as: "building_logins"
}
}
]);
res.send(building_rooms);
});
Note I have purposely not included $unwind
The current output for this request is:
[
{
"_id": "5c79a31ed2016312ecd27c46",
"name": "Park",
"site": {
"_id": "5c79a243d2016312ecd27c45",
"name": "Park Newcastle"
},
"__v": 0,
"building_rooms": [
{
"_id": "5c7fa01abdd6233d6fdbc917",
"name": "E101",
"building": {
"_id": "5c79a31ed2016312ecd27c46",
"name": "Park"
},
"__v": 0
},
{
"_id": "5c7fdbd12229db40589e41b5",
"name": "E202",
"building": {
"_id": "5c79a31ed2016312ecd27c46",
"name": "Park"
},
"__v": 0
}
],
"building_logins": [
{
"_id": "5c91483402d1a4145a2c4d9b",
"dateIn": "2019-03-19T19:51:06.458Z",
"user": {
"_id": "5c83b4b87321805bad025e65",
"email": "bob1999#gmail.com",
"isVisitor": true
},
"building": {
"_id": "5c79a31ed2016312ecd27c46",
"name": "Park"
},
"__v": 0,
"dateOut": "2019-03-20T11:55:19.205Z"
}
]
},
{
"_id": "5c925475e88bb72764283113",
"name": "Manchester",
"site": {
"_id": "5c921c94a922f6236cbe37d2",
"name": "Manchester"
},
"__v": 0,
"building_rooms": [
{
"_id": "5c7fa01abdd6233d6fdbc917",
"name": "E101",
"building": {
"_id": "5c79a31ed2016312ecd27c46",
"name": "Park"
},
"__v": 0
},
{
"_id": "5c7fdbd12229db40589e41b5",
"name": "E202",
"building": {
"_id": "5c79a31ed2016312ecd27c46",
"name": "Park"
},
"__v": 0
}
],
"building_logins": [
{
"_id": "5c91483402d1a4145a2c4d9b",
"dateIn": "2019-03-19T19:51:06.458Z",
"user": {
"_id": "5c83b4b87321805bad025e65",
"email": "bob1999#gmail.com",
"isVisitor": true
},
"building": {
"_id": "5c79a31ed2016312ecd27c46",
"name": "Park"
},
"__v": 0,
"dateOut": "2019-03-20T11:55:19.205Z"
}
]
}
]
However the issue is that the logins and rooms of 'Park' are being embedded in manchester building. which is not correct.
The correct output should be:
[
{
"_id": "5c79a31ed2016312ecd27c46",
"name": "Park",
"site": {
"_id": "5c79a243d2016312ecd27c45",
"name": "Park Newcastle"
},
"__v": 0,
"building_rooms": [
{
"_id": "5c7fa01abdd6233d6fdbc917",
"name": "E101",
"building": {
"_id": "5c79a31ed2016312ecd27c46",
"name": "Park"
},
"__v": 0
},
{
"_id": "5c7fdbd12229db40589e41b5",
"name": "E202",
"building": {
"_id": "5c79a31ed2016312ecd27c46",
"name": "Park"
},
"__v": 0
}
],
"building_logins": [
{
"_id": "5c91483402d1a4145a2c4d9b",
"dateIn": "2019-03-19T19:51:06.458Z",
"user": {
"_id": "5c83b4b87321805bad025e65",
"email": "bob1999#gmail.com",
"isVisitor": true
},
"building": {
"_id": "5c79a31ed2016312ecd27c46",
"name": "Park"
},
"__v": 0,
"dateOut": "2019-03-20T11:55:19.205Z"
}
]
},
{
"_id": "5c925475e88bb72764283113",
"name": "Manchester",
"site": {
"_id": "5c921c94a922f6236cbe37d2",
"name": "Manchester"
},
"__v": 0,
"building_rooms": [],
"building_logins": []
}
]
With there being no instances of building_rooms or building_logs as there are no logins or rooms with the object ID relating to manchester.
I really appreciate the time taken to read this and would be grateful for any help with solving tis problem.

mongoose: insert data into sub arrays

I'm I'm trying to create sub arrays with a mongoose and I have a dificulty to insert the subdocuments.
My schema is like this:
var SurveySchema = mongoose.Schema({
question_id: { type: String, unique: true },
question_text: { type: String, required: true },
//answer's object. will contain 4 answers
answers: { type:
[{
answer_id: { type: String, unique: true },
answer_text: { type: String, required: true },
next_question: { type: String, required: true },
platforms: {
type: [{
platform_id: { type: String, required: true },
platform_name: { type: String, required: true },
platform_weight: { type: Number, required: true },
}]
}
}]
}
});
var SurveySchemaExport = module.exports = mongoose.model('Survey', SurveySchema);
And the data that I want to insert into the db looks like this:
{
"question_id": "1",
"question_text": "Freddy",
"answers": [{
"answer_id": "1",
"answer_text": "test1",
"next_question": "ans02",
"platforms": [{
"platform_id": "1",
"platform_name": "Facebook",
"platform_weight": "0.5"
}]
},
{
"answer_id": "2",
"answer_text": "test2",
"platforms": [{
"platform_id": "1",
"platform_name": "Facebook",
"platform_weight": "0.2"
}]
}, {
"answer_id": "3",
"answer_text": "test3",
"platforms": [{
"platform_id": "1",
"platform_name": "Facebook",
"platform_weight": "0.3"
}]
}, {
"answer_id": "4",
"answer_text": "test4",
"platforms": [{
"platform_id": "1",
"platform_name": "Facebook",
"platform_weight": "0.7"
}]
}]
}
My insertion function is like this:
var input = req.body;
var newAlgoData = new SurveySchema({
question_id: input.question_id,
question_text: input.question_text,
answers: [input.answers],
next_question: input.next_question,
platforms: [input.answers.platforms]
})
console.log(newAlgoData);
var isCreated = newAlgoData.save((function (err) {
if (err){
return false;
} else{
return isCreated;
}
}))
The responce I get is:
{ _id: 5b79c144f0a8071048aa8f39,
question_id: '1',
question_text: 'Freddy',
answers: [ { _id: 5b79c144f0a8071048aa8f3a, platforms: [] } ] }
(node:4168) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: newAlgoData.save(...) is not a function
I know how to fix the "not a function" error' ,but my problem is with the insertion of the data into the db, specifically the data in the arrays.
Thank you very much for your help.

unable to populate articles in mongoose [duplicate]

This question already has answers here:
How to convert string to objectId in LocalField for $lookup Mongodb [duplicate]
(1 answer)
Querying after populate in Mongoose
(6 answers)
Closed 4 years ago.
I have the category schema like this:
var category_article_Schema = new Schema({
"article_id": { type: String, required: false, unique: false },
"category": String,
"articles": [{ type: mongoose.Schema.Types.ObjectId, ref:'article'}],
});
var category_article_Schema = mongoose.model('category_article_Schema', category_article_Schema);
module.exports = category_article_Schema;
Article schema:
var articleSchema = new Schema({
"title": { type: String, required: true, unique: false },
"details": String,
"username": { type: String, required: true, unique: false },
"postImageUrl": String,
"url": String,
"categories": [String],
"created_at": { type: Date, default: Date.now }
});
var article = mongoose.model('article', articleSchema);
module.exports = article;
When I try to populate articles in the below function, I get only category id and name but no articles populated.
function getPostByCategory(req, res, next) {
category_article_model.find({category: req.params.name}) //sports
.populate('articles')
.exec()
.then(function(articlesByCategory) {
console.log(articlesByCategory);
})
.catch(function(err){
console.log('err ', err);
})
}
All the data I have in article collection is this:
`{
"_id": {
"$oid": "5b0008ce8787890004989df1"
},
"categories": [
"sports",
"health"
],
"title": "sample",
"details": "sample ",
"created_at": {
"$date": "2018-05-19T11:21:50.837Z"
},
"__v": 0
},
{
"_id": {
"$oid": "5b0087646dda9600049a9a27"
},
"categories": [
"sports"
],
"title": "sample3333",
"details": " sample3333",
"created_at": {
"$date": "2018-05-19T20:21:56.126Z"
},
"__v": 0
}`
And category_article_schema collection has:
{
"_id": {
"$oid": "5b0087646dda9600049a9a28"
},
"category": "sports",
"article_id": "5b0087646dda9600049a9a27",
"__v": 0
}
But the data returned is empty array of article:
[ { articles: [],
_id: 5b0008ce8787890004989df2,
category: 'sports',
article_id: '5b0008ce8787890004989df1',
__v: 0 } ]
I am not sure what could be the issue?

Sequelize where condition for multiple tables not working

While building Sequelize query unable to filter data from two tables with two different where conditions. Here I am adding some code...
Models:
//Task model
module.exports = function(sequelize, DataTypes) {
var Task = sequelize.define("Task", {
type: DataTypes.STRING(100),
start : DataTypes.DATE,
finish : DataTypes.DATE,
status : DataTypes.STRING(1),
}, {
classMethods: {
associate: function(models) {
Task.belongsTo(models.User, {
onDelete: "CASCADE",
foreignKey: {
allowNull: true
}
});
Task.hasOne(models.Evaluation);
Task.hasMany(models.Clarification);
}
}
});
return Task;
};
//Evaluation model
module.exports = function(sequelize, DataTypes) {
var Evaluation = sequelize.define("Evaluation", {
agent_id : DataTypes.INTEGER,
agent_name: DataTypes.STRING(100),
status: DataTypes.STRING(100),
}, {
classMethods: {
associate: function(models) {
Evaluation.belongsTo(models.Task, {
onDelete: "CASCADE",
foreignKey: {
allowNull: false
}
});
Evaluation.hasMany(models.Clarification);
}
}
});
return Evaluation;
};
//Clarification model
module.exports = function(sequelize, DataTypes) {
var Clarification = sequelize.define("Clarification", {
result : DataTypes.TEXT,
status : DataTypes.STRING(100),
comment : DataTypes.TEXT
}, {
classMethods: {
associate: function(models) {
Clarification.belongsTo(models.Task, {
onDelete: "CASCADE",
foreignKey: {
allowNull: false
}
});
Clarification.belongsTo(models.Evaluation, {
onDelete: "CASCADE",
foreignKey: {
allowNull: false
}
});
}
}
});
return Clarification;
};
I just added required code not exactly same.
Actually Using:
var filterobj = {
where: {
"UserId": { $ne: "NULL" }
},
include: [{
model: models.Evaluation,
attributes: ["id", "status","agent_name"],
where: {
"status": { $ne: "created" }
},
include: [{
model: models.EvalForm,
attributes: ["id", "name","LobId"],
include: [{
model: models.Lob,
attributes: ["id", "ClientId"]
},
{
model: models.FormDetails,
attributes: ["version", "status"]
}
]
}, {
model: models.Clarification,
attributes: ["id", "status"]
}],
required: true
},{
model: models.User,
attributes: ["name"]
}]
};
models.Task.findAll(filterobj).then(function (tasklist) {
// Doing some stuff for specific format
return res.send(tasklist);
}).catch(function (err) {
return res.send({ "error": { "code": 5000, "message": err.message } });
});
Response:
[
{
"id": 760,
"type": "clarification",
"start": "2017-07-12T14:30:52.000Z",
"finish": "2017-07-13T05:41:56.000Z",
"status": "A",
"UserId": 854,
"Evaluation": {
"id": 760,
"status": "completed",
"agent_name": "TestAgent1",
"EvalForm": {
"id": 5000008,
"name": "MobiPostpaid1",
"LobId": 26,
"Lob": {
"id": 26,
"ClientId": 1
},
"FormDetails": [
{
"version": 1,
"status": "A"
}
]
},
"Clarifications": [
{
"id": 70,
"status": "raised"
},
{
"id": 71,
"status": "esclate"
}
]
},
"User": {
"name": "pooja.s"
}
},
{
"id": 761,
"type": "clarification",
"start": "2017-07-12T14:30:52.000Z",
"finish": "2017-07-12T14:35:30.000Z",
"status": "A",
"UserId": 854,
"Evaluation": {
"id": 761,
"status": "assigned",
"agent_name": "TestAgent1",
"EvalForm": {
"id": 5000008,
"name": "MobiPostpaid1",
"LobId": 26,
"Lob": {
"id": 26,
"ClientId": 1
},
"FormDetails": [
{
"version": 1,
"status": "A"
}
]
},
"Clarifications": []
},
"User": {
"name": "pooja.s"
}
}
]
Expected Code(Not working)
var filterobj = {
where: {
"UserId": { $ne: "NULL" }
},
include: [{
model: models.Evaluation,
where: {
"status": { $in: ["assigned","completed"] }
},
attributes: ["id", "status","agent_name"],
include: [{
model: models.EvalForm,
attributes: ["id", "name","LobId"],
include: [{
model: models.Lob,
attributes: ["id", "ClientId"]
},
{
model: models.FormDetails,
attributes: ["version", "status"]
}
]
}, {
model: models.Clarification,
attributes: ["id", "status"]
}],
required: true
},{
model: models.User,
attributes: ["name"]
}, {
model: models.Clarification,
where: {
"status": { $in: ["raised"] }
}
attributes: ["id", "status"]
}]
};
models.Task.findAll(filterobj).then(function (tasklist) {
// Doing some stuff for specific format
return res.send(tasklist);
}).catch(function (err) {
return res.send({ "error": { "code": 5000, "message": err.message } });
});
Expected Response:
[
{
"id": 760,
"type": "clarification",
"start": "2017-07-12T14:30:52.000Z",
"finish": "2017-07-13T05:41:56.000Z",
"status": "A",
"UserId": 854,
"Evaluation": {
"id": 760,
"status": "completed",
"agent_name": "TestAgent1",
"EvalForm": {
"id": 5000008,
"name": "MobiPostpaid1",
"LobId": 26,
"Lob": {
"id": 26,
"ClientId": 1
},
"FormDetails": [
{
"version": 1,
"status": "A"
}
]
},
"Clarifications": [
{
"id": 70,
"status": "raised"
},
{
"id": 71,
"status": "esclate"
}
]
},
"User": {
"name": "pooja.s"
},
"Clarifications": [
{
"id": 70,
"status": "raised"
}
]
},
{
"id": 761,
"type": "clarification",
"start": "2017-07-12T14:30:52.000Z",
"finish": "2017-07-12T14:35:30.000Z",
"status": "A",
"UserId": 854,
"Evaluation": {
"id": 761,
"status": "assigned",
"agent_name": "TestAgent1",
"EvalForm": {
"id": 5000008,
"name": "MobiPostpaid1",
"LobId": 26,
"Lob": {
"id": 26,
"ClientId": 1
},
"FormDetails": [
{
"version": 1,
"status": "A"
}
]
},
"Clarifications": []
},
"User": {
"name": "pooja.s"
},
"Clarifications": []
}
]
I can include Clarification table inside Task and Evaluation tables I have that association. The problem with where condition. It is pulling all the records. I am expecting data from Clarification table with status raised. And from Evaluation table status with assigned and completed. Some where I saw code using OR operator.
A.findAll({
where: {
$or: [
{'$B.userId$' : 100},
{'$C.userId$' : 100}
]
},
include: [{
model: B,
required: false
}, {
model: C,
required: false
}]
});
But this is not working for me.

Categories

Resources