How to stop MongoDB to add values to my objects? - mongodb

I'm writing a little personal project requiring to write into a db and getting content to be displayed with d3js. So I'm using objects containing like {x: "2004-10-02", y:20} etc... Now I found that mongoDB adds y0:0 and even y1: 20 when I change the value of y using $set with Mongoose.
I have this Schema:
var projectSchema = mongoose.Schema({
key : String,
description: String,
values: [{x: Date, y: Number, comment: String}]
});
It works fine. I can insert documents (incomplete model) sending a request with this body:
{
name: "name of the Project",
description: "insert descritption"
}
and process the request with this:
var newProjectDetails = req.body;
var np = new Project(newProjectDetails);
np.save(function (err) {
if (err) {
return err;
}
else {
console.log("Project saved");
}
});
then I add values to the values array (see above the Schema) and it works fine the first time, but if I try to overwrite an entry in the array I get this a messed object, with extra values that seem to be old values of the y property.
Here's how I add an entry into the values array:
Project.findByIdAndUpdate(req.body._id,
{ $set: { values: req.body.values } },
function(err, tank){
if(err){
res.send(err);
}
res.send(tank);
})
But then when I fetch the content I got a strange issue inside the array:
I get this object in the console:
{
"x": "2014-10-12T00:00:00.000Z",
"y": 20,
"comment": "doanjas dfgixGHWXV",
"_id": "543a96c3a402c9ad17528d52"
}
and this in RestWebServiceClient extention in Chrome:
{
"x": "2014-10-12T00:00:00.000Z",
"y": 20,
"comment": "doanjas dfgixGHWXV",
"_id": "543a96c3a402c9ad17528d52"
}
But inside the console, when I iterate through the collection with Angular I get this:
{ _id: "543a96c3a402c9ad17528d52",
comment: "doanjas dfgixGHWXV",
series: 0,
size: 20,
x: "2014-10-12T00:00:00.000Z",
y: 20,
y0: 0,
y1: 20
}
This is driving me crazy, should I map the array and get rid of this, why would I do that extra work?

Related

Mongodb: Could the objects in array with $oid be populate?

Has anyone ever used the objects in array with $oid and populate it?
Every class will have different is semester.So I use array to contain some detail of each semester,and have $oid for them.
boards:
{"_id":{"$oid":"63a07ecf6973176c890c8737"},
"classname":"math",
"uniqueData":[
{"semester":"2022-1","score":2,"_id":{"$oid":"63a07ec77777777777777777"}},
{"semester":"2022-2","score":2,"_id":{"$oid":"63a07ec88888888888888888"}}
],
}
reviews:
{
"uniqueId":{"$oid":"63a07ec77777777777777777"},
"score": 8
}
The review will point to certain class.semester. So I hope use populate to display the detail of that semester.
schemaReviews.find({}).populate({path: 'uniqueId'})
//I get:
{
"uniqueId":null,
"score": 8
}
//But I need:
{
"uniqueId":
{"semester":"2022-1","score":2,"_id":{"$oid":"63a07ec77777777777777777"}}
,
"score": 8
}
How do I got this done?
The models:
//
const schemaBoards = new mongoose.Schema({
classname:string
uniqueData:[{semester:string,score:int}],
})
mongoose.model('boards', schemaBoards)
//
const schemaReviews = new mongoose.Schema({
uniqueId: {
type: mongoose.ObjectId,
ref: 'boards'
},
score: Int
})
mongoose.model('reviews', schemaReviews)
Any Idea?

Mongoose add or update values in an array inside an object inside an array

This is my schema,
const courseSchema = new mongoose.Schema({
name: String,
code: String,
class: String,
credit: Number,
overview: String,
prerequisite: String,
syllabus: [
{
moduleName: String,
moduleDetails: String,
},
],
materials: [
{
moduleNo: Number,
moduleMaterials: [String],
},
],
teacher: String,
students: [String],
});
I want to add new materials in which each time an update operation is called I receive a
moduleNo and a materialURL.
I want to add this to the materials array in my existing course which is filtered by courseID. So each time I receive a moduleNo and a materialURL, I want to check if moduleNo already exists in the materials array. If yes, then add materialURL into the moduleMaterials array without deleting the existing urls in moduleMaterials. If no, then add a new object with moduleNo and moduleMaterials and materialURL pushed into moduleMaterials. I've heard about upsert and think that could be used but I'm not sure what the correct queries are to do this operation.
What I've currently come up with even though it's wrong,
Course.updateOne(
{ _id: courseID },
{
$push: {
materials: { moduleNo, moduleMaterials: { $push: { materialURL } } },
},
},
{ upsert: true },
(err, result) => {
if (err) {
console.error(err);
} else {
console.log(result);
}
}
);
How do I do execute this query?

Documents inserted without schema not being found with schema

I have two new collections in MongoDB of data that I pulled from an old Firestore database that I'm moving to mongo. Since the total number between these two collections is roughly 20,000, I opted to paste the raw JSON into the insert document section in mongo, which worked like a charm and I didn't have to write a new insert route to do the same.
I then created a schema in Mongoose that matched the inserted documents, and tried to use the schema to pull back some data, and its always returning nothing.
An example of a ticket inserted via JSON:
{
"title": "How to add and manage users for your company in QuickBooks Online",
"priority": "1",
"type": "Video",
"course": "G205",
"transcriptId": "07dom27Zz98jakvB1oh5",
"status": "In Review",
"tags": "",
"url": "",
"revisionNumber": 0,
"directoryId": 19,
"checkedOut": false
},
And my schema I made to match. The collection name in mongo is also called oldTickets, the plural of my schema name here:
const mongoose = require('mongoose');
var Schema = mongoose.Schema
const schema = new Schema({
course: { type: String },
title: { type: String },
priority: { type: String },
type: { type: String },
course: { type: String },
transcriptId: { type: String },
status: { type: String },
tags: { type: String },
url: { type: String },
revisionNumber: { type: Number },
directoryId: { type: Number },
checkedOut: { type: Boolean },
});
module.exports = mongoose.model('oldTicket', schema);
And finally my model import and fetch call:
const OldTicket = require('./models/model_old_ticket');
/***************************************************************************
* Get Old Tickets - Returns all old tickets, 10 at a time
****************************************************************************/
app.get('/getOldTickets/:offset', (req, res) => {
checkConnection();
OldTicket.find().skip(parseInt(req.params.offset)).limit(10).exec((err, data) => {
if (err){ res.status(500).send({err: err}); }
//If we got data, count the tickets & return the tickets & count
if (data) {
OldTicket.find().countDocuments().then(count => {
return res.status(200).send({
tickets: data,
count: count
})
})
}
});
});
Why isn't this finding anything? Both the count and the tickets are 0. I've run into this issue before when manually creating a collection without a schema, and in those instances I would simply delete the collection, write a route to create a document, and then things would work fine. But with the large data size of these two collections, I'd rather not do that since everything should be working as is.
Edit: Example of document in Mongo
And the name of the collection I'm currently viewing:
And I just now realized that for some reason there are now two collection names, oldTickets, which has data, and oldtickets, which is empty. I'm assuming my query is searching through the empty one? How can I get it to go to the one that actually has data?
can you attach the screenshot of your data with the collection? might be it's different.in mongoose, every collection name is complete with 's'. please verify your collection is created manually by you then it has to same as mongoose schema and also completed with 's'.
example:
const mongoose = require("mongoose");
const schema = new mongoose.Schema(
{
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
index: true
},
filmId: {
type: mongoose.Schema.Types.ObjectId,
index: true
},
filmType: {
type: String,
index: true
},
birthday: {
type: Date
},
age: {
type: Number
},
terms: {
type: Boolean
}
},
{
versionKey: false,
timestamps: true,
}
);
schema.index({ filmId: 1, user: 1 })
module.exports = mongoose.model("UserAgeVerification", schema);
see my database

Store array of string into the mongoDB collection

I am very new to MongoDB and mongoose I have a model name called agent
agent.model.js
const mongoose = require('mongoose')
const agentSchema = new mongoose.Schema({
agent: {
type: String,
required: true
}
})
const Agent = mongoose.model('Agent', agentSchema)
module.exports = Agent;
Now I have a array of string:
const agentName = ['john', 'alex', 'david'];
Now I want to store this array into the mongoDB as an individual agent.
like this:
[
{
"_id": "6000977d9b94f52960955066",
"agent": "john",
"__v": 0
},
{
"_id": "6000977d9b94f52960955067",
"agent": "alex",
"__v": 0
},
{
"_id": "6000977d9b94f52960955068",
"agent": "david",
"__v": 0
}
]
Note: Right now First I am converting my array of string into the array of object using loop like this:
agentName = agentName.map((e) => {return {agent: e}})
//output of above line of code
[ { agent: 'Alex Watson' },
{ agent: 'John Snow' },
{ agent: 'Rita Ora' } ]
Then I am saving the agentName.
But I am looking for some better approach, Like in which there is no need of converting the array of string into the array of object.
you must to use insertMany() function is used to insert multiple documents into a collection. It accepts an array of documents to insert into the collection. like following code, so have to create a array of abjects, that you created
note: in your question define const agentName next step assign result of map to the constant variable, so this is wrong
const agentName = ['john', 'alex', 'david'];
let arr = agentName.map((e) => {return {agent: e}})
Agent.insertMany(arr).then(function(){
console.log("Data inserted") // Success
}).catch(function(error){
console.log(error) // Failure
});

Distinct Query with Cloudant Connector using Loopback in API Connect/StrongLoop

I am trying to get distinct values for a query using Loopback with a Cloudant Connector, but I haven't found anything about this in the documentation.
e.g. I need a query to turn this:
[
{
rating: "★★★★★"
},
{
rating: "★★★★★"
},
{
rating: "★★★★★"
},
{
rating: "★★★★★"
},
{
rating: "★★★☆☆"
},
{
rating: "★★★☆☆"
}
]
into this:
[
{
rating: "★★★★★"
},
{
rating: "★★★☆☆"
}
]
I'm using the REST API to query my Products model (above is a filtered view of just the rating field). If there is some sort of filter that I can use without modifying the server that I somehow just missed in the documentation, that would be the best choice.
Is there any way I can add a distinct field like:
/Products?filter[fields][rating]=true?distinct=true
or how can I go about solving this?
Also, I've seen another answer talking about adding a remote method to solve this (something like this for mySQL):
Locations.regions = function (cb) {
var ds = Locations.app.datasources.myDS;
var sql = "SELECT DISTINCT region FROM Locations ORDER BY region"; // here you write your sql query.
ds.connector.execute(sql, [], function (err, regions) {
if (err) {
cb(err, null);
} else {
cb(null, regions);
}
});
};
Locations.remoteMethod(
'regions', {
http: {
path: '/regions',
verb: 'get'
},
returns: {
root: true,
type: 'object'
}
}
);
If this would work, how would I implement it with the Cloudant NoSQL DB connector?
Thanks!
If your documents looked like this:
{
"name": "Star Wars",
"year": 1978,
"rating": "*****"
}
You can create a MapReduce view, which emits doc.rating as the key and uses the build-in _count reducer:
function(doc) {
emit(doc.rating,null);
}
When you query this view with group=true, distinct values of rating will be presented with counts of their occurrence in the data set.