My Model which has coure_name, c_material as array, c_task as array and I am trying to fetch the results based on the below query:
const taks_schema = mongoose.Schema({
course_name : {
type : String,
required : true,
unique : [true, "Someone register using this email"],
trim : true
},
c_material : [
{
m_name : {
type : String
},
m_link : {
type : String
},
m_file : {
type : String
},
m_date : {
type : String
}
}
],
c_task : [
{
t_name : {
type : String
},
t_details : {
type : String
},
t_start_date : {
type : Date
},
t_end_date : {
type : Date
},
t_q_file : {
type : String
},
t_s_file : [
{
t_s_email: {
type : String
},
t_s_file_inner : {
type : Array
},
t_s_file_Date : {
type : Date
}
}
]
}
]
});
I apply this query which searches through the database, but get 0 modified in the result object.
let submit_files = await stu_task.updateOne({$and: [{course_name : "Web Development with Node js"}, {c_task : {_id : req.body.task_id}}]}, {$set : {c_task : {t_s_file : {t_s_email : check_cookie.email, t_s_file_inner : files_names, t_s_file_Date : Date.now()}}}});
Is there any problem in the query that I have created?
You don't have "c_task._id" defined in the schema , but you have it in the updateOne search criteria ...
You also need arrayFilters to update nested arrays check the documentation and also you need a id to search in t_s_file array in following query is used t_s_email field because I don't know the real data, so I searching in t_s_file based on t_s_email can using _id if exist
await stu_task.updateOne(
{
$and: [
{ course_name: "Web Development with Node js" },
{ "c_task._id": req.body.task_id },
],
},
{
$set: {
"c_task.$[].t_s_file.$[i].t_s_email": {
t_s_email: check_cookie.email,
t_s_file_inner: files_names,
t_s_file_Date: Date.now(),
},
},
},
{ arrayFilters: [{ "i.t_s_email": "email#gmail.com" }] }
);
Related
const apprenticeshipstandards = await Apprenticeshipstandard.find();
it returns the data in more than 4 mins. any better way of querying find() to mongodb docs? it was working fine but suddenly started taking more than 4 mins fetch all docs
This is my schema actually fetching the data from external api and replicating into my database. now trying to fetch it from my own database and its taking too long to fetch.
const mongoose = require('mongoose');
const ApprenticeshipstandardsSchema = mongoose.Schema({
templateType : {
type : String
},
larsCode : {
type : String,
},
referenceNumber : {
type : String,
required : true
},
title : {
type : String,
required : true
},
status : {
type : String,
required : true
},
url : {
type : String
},
versionNumber : {
type : String
},
change : {
type : String
},
changedDate : {
type : String
},
earliestStartDate : {
type : String
},
latestStartDate : {
type : String
},
latestEndDate : {
type : String
},
overviewOfRole : {
type : String
},
level : {
type : Number
},
typicalDuration : {
type : Number
},
maxFunding : {
type : Number
},
route : {
type : String
},
keywords : {
type : Array
},
jobRoles : {
type : Array
},
entryRequirements : {
type : String
},
assessmentPlanUrl : {
type : String
},
ssa1 : {
type : String
},
ssa2 : {
type : String
},
version : {
type : String
},
standardInformation : {
type : String
},
occupationalSummary : {
type : String
},
knowledges : {
type : Array
},
behaviours : {
type : Array
},
skills : {
type : Array
},
options : {
type : Array
},
optionsUnstructuredTemplate : {
type : Array
},
proposalApproved : {
type : String
},
standardApproved : {
type : String
},
epaApprovalDate : {
type : String
},
fundingApprovalDate : {
type : String
},
eQAProvider : {
type : Object
},
approvedForDelivery : {
type : String
},
integratedApprenticeship : {
type : Boolean
},
integratedDegree : {
type : String
},
tbReference : {
type : String
},
tbMainContact : {
type : String
},
involvedEmployers : {
type : String
},
regulated : {
type : Boolean
},
regulatedBody : {
type : String
},
coreAndOptions : {
type : Boolean
},
typicalJobTitles : {
type : Object
},
greenJobTitles : {
type : Object
},
englishAndMathsQualifications : {
type : String
},
reviewDetails : {
type : String
},
pathway : {
type : Object
},
cluster : {
type : Object
},
createdDate : {
type : String
},
lastUpdated : {
type : String
},
occupationalStandardUrl : {
type : String
},
standardPageUrl : {
type : String
},
qualifications : {
type : Array
},
professionalRecognition : {
type : Array
},
duties : {
type : Array
},
regulationDetail : {
type : Array
},
optionsUnstructuredKsbMapping : {
type : Array
},
careerStarter : {
type : Boolean
},
});
module.exports = mongoose.model('Apprenticeshipstandards', ApprenticeshipstandardsSchema);
This is the explain plan
{"explainVersion":"1","queryPlanner":{"namespace":"RubitekDB.apprenticeshipstandards","indexFilterSet":false,"parsedQuery":{},"maxIndexedOrSolutionsReached":false,"maxIndexedAndSolutionsReached":false,"maxScansToExplodeReached":false,"winningPlan":{"stage":"COLLSCAN","direction":"forward"},"rejectedPlans":[]},"executionStats":{"executionSuccess":true,"nReturned":1011,"executionTimeMillis":13,"totalKeysExamined":0,"totalDocsExamined":1011,"executionStages":{"stage":"COLLSCAN","nReturned":1011,"executionTimeMillisEstimate":12,"works":1013,"advanced":1011,"needTime":1,"needYield":0,"saveState":1,"restoreState":1,"isEOF":1,"direction":"forward","docsExamined":1011},"allPlansExecution":[]},"command":{"find":"apprenticeshipstandards","filter":{},"skip":0,"limit":0,"maxTimeMS":60000,"$db":"RubitekDB"},"serverInfo":{"host":"ac-hwcjvc4-shard-00-02.rwi1fym.mongodb.net","port":27017,"version":"5.0.13","gitVersion":"cfb7690563a3144d3d1175b3a20c2ec81b662a8f"},"serverParameters":{"internalQueryFacetBufferSizeBytes":104857600,"internalQueryFacetMaxOutputDocSizeBytes":104857600,"internalLookupStageIntermediateDocumentMaxSizeBytes":16793600,"internalDocumentSourceGroupMaxMemoryBytes":104857600,"internalQueryMaxBlockingSortMemoryUsageBytes":33554432,"internalQueryProhibitBlockingMergeOnMongoS":0,"internalQueryMaxAddToSetBytes":104857600,"internalDocumentSourceSetWindowFieldsMaxMemoryBytes":104857600},"ok":1,"$clusterTime":{"clusterTime":{"$timestamp":"7158726415230173191"},"signature":{"hash":"g2I1o5BLMSdftjXrP0sffIDyIM8=","keyId":{"low":11,"high":1655126098,"unsigned":false}}},"operationTime":{"$timestamp":"7158726415230173191"}}
my Test Schema:
var TestSchema = new Schema({
testName: String,
topic: {
topicTitle: String,
topicQuestion: [
{
questionTitle: String,
choice: [
{
name: String
age: Number
}
]
}
]
}
}, { collection: 'test' });
var Test = mongoose.model('test', TestSchema);
I want to update one age ($inc)value which I have the choice id.
I can have test id, topicQuestion id and choice id.
How to write this query in mongoose in NodeJS?
Normally I use the below query to update a value:
Test.findOneAndUpdate({ _id: testId }, { $inc: { ... } }, function (err, response) {
...
});
but it is so difficult to get in array and one more array. Thanks
You can use the $[] positional operator to update nested arrays.
router.put("/tests/:testId/:topicQuestionId/:choiceId", async (req, res) => {
const { testId, topicQuestionId, choiceId } = req.params;
const result = await Test.findByIdAndUpdate(
testId,
{
$inc: {
"topic.topicQuestion.$[i].choice.$[j].age": 1
}
},
{
arrayFilters: [{ "i._id": topicQuestionId }, { "j._id": choiceId }],
new: true
}
);
res.send(result);
});
Let's say we have this existing document:
{
"_id" : ObjectId("5e53e7d9bf65ac4f5cbf2116"),
"testName" : "Test 1",
"topic" : {
"topicTitle" : "Title",
"topicQuestion" : [
{
"_id" : ObjectId("5e53e7d9bf65ac4f5cbf211a"),
"questionTitle" : "Question 1 Title",
"choice" : [
{
"_id" : ObjectId("5e53e7d9bf65ac4f5cbf211c"),
"name" : "A",
"age" : 1
},
{
"_id" : ObjectId("5e53e7d9bf65ac4f5cbf211b"),
"name" : "B",
"age" : 2
}
]
},
{
"_id" : ObjectId("5e53e7d9bf65ac4f5cbf2117"),
"questionTitle" : "Question 2 Title",
"choice" : [
{
"_id" : ObjectId("5e53e7d9bf65ac4f5cbf2119"),
"name" : "C",
"age" : 3
},
{
"_id" : ObjectId("5e53e7d9bf65ac4f5cbf2118"),
"name" : "D",
"age" : 4
}
]
}
]
},
"__v" : 0
}
If we want to increment age value of a given choice, we send a PUT request using endpoint like this http://.../tests/5e53e7d9bf65ac4f5cbf2116/5e53e7d9bf65ac4f5cbf211a/5e53e7d9bf65ac4f5cbf211b where
"testId": "5e53e7d9bf65ac4f5cbf2116"
"topicQuestionId": "5e53e7d9bf65ac4f5cbf211a"
"choiceId": "5e53e7d9bf65ac4f5cbf211b"
You need to inform what choice you want and, on the update section, you need change the way you do increment.
Example:
Test.findOneAndUpdate({ _id: testId, topicQuestion.choice._id: choiceId}, { 'topicQuestion.$.choice': {$inc: { age: <numberToIncrement> }}}, {new: true}, function (err, response) {
...
});
I can't really figure out how to return nested fields within array of objects. Here is my schema:
const chat = new Schema({
id: {
type: String,
required: true
},
channels: [
{
id: {
type: String
},
messages: [
{
author: String,
body: String,
created_at: Date,
_id: false,
avatar: String
}
]
}
]
})
I want to receive 50 channel messages by using chat ID and channel ID from specific range provided by user (0-49, 50-99 and so on).
So in the end I receive array of objects from that channel.
const messages = [{...}, {...}, ...]
Just a different variation of the first answer to actually return ONLY the required channel and not all of them.
db.getCollection("collection").aggregate(
[
{
"$match" : {
"id" : chatid
}
},
{
"$unwind" : "$channels"
},
{
"$match" : {
"channels.id" : channelid
}
},
{
"$project" : {
"messages" : {
"$slice" : [
"$channels.messages",
0.0,
50.0
]
}
}
}
]
);
I'd use the aggregation pipeline for this. I haven't used mongoose but for a basic mongo query it'd look like:
db.getCollection("collection").aggregate(
[
{
//find the matching documents
"$match" : {
"id" : "chatid",
"channels.id" : "channelid"
}
},
{
//split the document into the individual messages
"$unwind" : "$channels.messages"
},
{
"$match" : {
"channels.id" : "channelid"
}
},
{
//limit to 50 (can be after the project stage)
"$limit" : 50
},
{
//update to just return the message subdoc
"$replaceRoot" : {
"newRoot" : "$channels.messages"
}
}
]
);
For mongoose check the aggregation API or aggregation middleware docs to implement this
i've encountered some error with my schema on mongoose.
my schema looks like:
{
accomodations : {
rooms : {
type : [{
rooms : [{
type : {
id : { type : Number },
name : {
ita : { type : String },
eng : { type : String },
},
numberOfRooms : { type : Number },
},
}],
boards : [{
id : { type : String },
type : {
id : { type : Number },
name : {
ita : { type : String },
eng : { type : String },
},
},
amount : {
currency : { type : String },
directPayment : { type : Boolean },
totalPrice : { type : Number },
mandatory : { type : Boolean },
priceAgency : { type : Number },
refundable : { type : Boolean },
markupPrice : { type : Number },
},
}],
amenities : [{ type : mongoose.Schema.Types.Mixed }],
}],
},
}
}
if i use "type" as property name i receive an error:
Invalid schema configuration: [object Object] is not a valid type within the array rooms.See http:// bit.ly /mongoose-schematypes for a list of valid schema types.
it's required for me have a property called type in my schema.
You should never have a field called type. It’s a reserved word in many languages and causes much hassle. Unsure what language you are using I recommend trying to rename to ‘roomType’
const mongoose = require('mongoose');
const orgSchema = new mongoose.Schema({
org_name : {
type : String,
required : true
},
admin : {
type : String,
required : true
},
branches : [{
branch_name : {
type : String,
required :true
},
branch_admin : {
type : String,
required : true
},
branch_locations : [{
_id : false,
sub_branch_name : {
type : String
},
sub_branch_admin : {
type : String
}
}]
}],
plan : {
type : mongoose.Schema.Types.ObjectId,
ref : 'plan',
required : true
},
status : {
type : String,
enum : ['ACTIVE', 'EXPIRED']
}
});
orgSchema.createIndex = ({
org_name : 1
},{
unique : true
});
module.exports = mongoose.model('organizations', orgSchema);
//Above is schema
{
"_id" : ObjectId("5bf91a1edc7ed22ca90d4624"),
"org_name" : "xxxxxxxxxxxxxxx",
"admin" : "sssssss",
"branches" : [
{
"_id" : ObjectId("5bf91a1edc7ed22ca90d4625"),
"branch_name" : "ssssss",
"branch_admin" : "ddd",
"branch_locations" : [
{}//automatically creates empty doc when no fields
]
}
],
"plan" : ObjectId("5bf91a1edc7ed22ca90d4623"),
"status" : "ACTIVE",
"__v" : 0
}
when i try to insert a document with empty fields in the sub document array, it returns with {} in array of sub document.
How to get rid from the new empty document in sub document. I should get an empty array when there is no field in the sub document to save...