one way direction, sails and mongodb - node.js

I have a question. I think i am doing something wrong.
I have two models:
tutorType and Student.
Here is my Student
module.exports = {
attributes: {
tutor1Name:'string',
tutor1Type: {
model: 'tutorType'
},
contact: {
type: 'numeric'
},
}
};
And here is my TutorType
module.exports = {
attributes: {
libelle: "string"
}
};
I use the predefined blue print to insert. When i Insert a new student
I have the returned response:
{
"name": "Luke",
"tutor1Type": "Biological",
"createdAt": "2015-07-13T17:57:12.526Z",
"updatedAt": "2015-07-13T17:57:12.526Z",
"id": "55a3fbf8c9e93bf0266a63a8"
}
Should tutor1Type be an object instead of a String? Actually, I can put the string I want. I would like to be able to put only rows i have in TutorType with a foreign key on my Student.
What wrong I do?!
EDIT
Just add a look in my DB.
When I send the ID of the tutorType to my controller. It add an "Object(hashID)" in db. I presume that is a good news.
The things is that I can also insert string that are not into my tutorList...
I do not understand how integrity work right here...
Any ideas?!

Related

MongoDB: Replace object in array

I am trying to replace/update a whole object in an array to it's latest values, but I cannot get it to work.
Db looks like this: (Note: there is only 1 main object in this collection)
{
"_id": {...},
"something that doesnt matter": {...},
"var1": {
"var2": [{...}, {...}, {...}, {...}, {...}],
"var3": [{...}, {...}, {...}, {...}, {...}]
},
"something that doesnt matter": {...}
}
I need to update a certain object from array var2, I have the object ID or there is a custom ID in the object that I can also get it with (id == updatedObject.id)
This worked but I cannot get it to work with a custom array id
await db.collection("collectionName").findOneAndUpdate(
{"var1.var2": { $exists: true }},
{ $set: { "var1.var2.1": updatedObject } }
);
I have the ID of the object already in the array on the db, but idk how to update it from var1.var2.ID,
so basically what I need is { $set: { "var1.var2.**ID**": updatedObject } } but I cant seem to find out how to get it to work.
Cause I dont want to update the whole array, and I also dont want to update a single variable in the object. I need to update the whole object.
Thank you in advance for your replies.
Have you tried as below
await db.collection("collectionName").findOneAndUpdate(
{
"var1.var2.id": id // id value (or any matching field) of object inside array you want to update
},
{
$set: {
"var1.var2.$": updatedObject // Update with new object
}
}
);
Hope this official mongodb documentation helps better for your requirement.
Sorry, I'm not able to comment but the above answer is almost correct except that you have to filter by var1.var2._id instead of var1.var2.id because mongodb default ID field is _id

How to find specific array inside JSON file with Mongoose [duplicate]

This question already has answers here:
Retrieve only the queried element in an object array in MongoDB collection
(18 answers)
Closed 3 years ago.
I made some complex data with mongoose schema.
And I want to find it by some specific condition.
Here is my data that is sent by post.
{
"clientID": "1234",
"clientOrder": [{
"cartNumber":0,
"departure": {
"pickUpTimeFrom": "2019-02-03T13:00",
"pickUpTimeto": "2019-02-03T15:00"
},
"destination": {
"pickUpTimeFrom": "2019-02-04T13:00",
"pickUpTimeto": "2019-02-04T15:00"
}
},
"clientID": "1234",
"clientOrder": [{
"cartNumber":1,
"departure": {
"pickUpTimeFrom": "2019-02-03T13:00",
"pickUpTimeto": "2019-02-03T15:00"
},
"destination": {
"pickUpTimeFrom": "2019-02-04T13:00",
"pickUpTimeto": "2019-02-04T15:00"
}
}]
}
And I want to find a specific array by the condition of date at "cartNumber: 0".
So, I made this find "cartNumber:0".
But, it doesn't send any date.
And , I couldn't make date condition like "2019-02-03" of "departure" even.
Could you help me to make the correct code?
const allInform = await Order.find({
clientOrder: {
$elemMatch: {
cartNumber: 0,
},
},
});
I'm not quite sure i understood your schema as it has some mistakes,
But i'm assuming each client order can have more than 1 cart and that cart#0 is not necessarly at index 0 of the array.
If any of these 2 assumptions are wrong this following query could be simplified.
let results = await Order.aggregate([
{
$unwind: "$clientOrder"
},
{
$match: {
$and: [{'clientOrder.cartNumber': 0},
{'clientOrder.destination.pickUpTimeFrom': <DATE OBJECT>}]
}
}
]);
notice assuming you saved the dates as a Date object you cant query it as a string.
If your using mongoshell use ISODate, it looks like: ISODate("2018-07-05T07:15:09.703+0000")
If your using javascript you can create a new date object: new Date(""2018-07-05")
when your matching dates like this it has to be an EXACT match.

How to fetch an object in Moogose

I'm trying to learn Mongoose and I'm trying to make a simple project. However, I can't understand how to do this.
I have a Schema like this (below) and I want to try to fetch results in this way...
Example: I want to get roleID where gameID is 111
How can do it?
I tried to search solution on google but I still don't understand how to make it without create object for any game I put in array
If I correctly understand you, you need something like this
aggregate(
[
{
$unwind: '$games'
},
{
$match: {
'games.gameId': "111"
}
},
{
$group: {
_id: '$games.gameId',
roles: {
$addToSet: '$games.roleId'
}
}
}
]
)

Editing/Updating nested objects in documents CouchDB (node.js)

I'm trying to add (aka. push to existing array) in couchDB document.
Any feedback is greatly appreciated.
I have a document called "survey" inside my database called "database1".
I have "surveys" as a set of arrays which consists of objects that has information on each survey.
My goal is to update my "survey" document. Not replacing my array, but adding a new object to the existing array. I've used "nano-couchdb" and "node-couchdb", but could not find a way around it. I was able to update my "surveys", but it would replace the whole thing, not keeping the existing objects in array.
1) Using Nano-couchdb:
db.insert({ _id, name }, "survey", function (error, resp) {
if(!error) { console.log("it worked")
} else {
console.log("sad panda")}
})
2) Using couchdb-node:
couch.update("database1", {
_id: "survey",
_rev:"2-29b3a6b2c3a032ed7d02261d9913737f",
surveys: { _id: name name: name }
)
These work well with adding new documents to a database, but doesn't work with adding stuff to existing documents.
{
"_id": "survey",
"_rev": "2-29b3a6b2c3a032ed7d02261d9913737f",
"surveys": [
{
"_id": "1",
"name": "Chris"
},
{
"_id": "2",
"name": "Bob"
},
{
"_id": "1",
"name": "Nick"
}
]
}
I want my request to work as it would for
"surveys.push({_id:"4",name:"harris"})
whenever new data comes in to this document.
Your data model should be improved. In CouchDB it doesn't make much sense to create a huge "surveys" document, but instead store each survey as a separate document. If you need all surveys, just create a view for this. If you use CouchDB 2.0, you can also query for survey documents via Mango.
Your documents could look like this:
{
"_id": "survey.1",
"type": "survey",
"name": "Chris"
}
And your map function would look like that:
function (doc) {
if (doc.type === 'survey') emit(doc._id);
}
Assuming you saved this view as 'surveys' in the design doc '_design/documentLists', you can query it via http://localhost:5984/database1/_design/documentLists/_view/surveys.

Combine Mongo Output with Node for API

I''m really new to Node but I currently have a NodeJS / Express open source CMS and would like to output some API data for an app that I am working. Forgive me if I'm not using the correct terminology or whatnot, this is new to me.
What I currently have are two collections, locations and tours. The CMS allows me to create a relationship between the two. This simply stores an array of ObjectID's in the locations record for each associated tour record.
What I want to do is take my API output code (below) and have it output the entire tours array, complete with all the fields (title, description, etc), in with each location record. Currently it only outputs an array of the ID's.
Here is my current code:
var async = require('async'),
landmark = require('keystone');
var Location = keystone.list('Location'),
Tour = keystone.list('Tour');
/**
* List Locations
*/
exports.list = function(req, res) {
Location.model.find(function(err, items) {
if (err) return res.apiError('database error', err);
res.apiResponse({
locations: items
});
});
}
/**
* Get Location by ID
*/
exports.get = function(req, res) {
Location.model.findById(req.params.id).exec(function(err, item) {
if (err) return res.apiError('database error', err);
if (!item) return res.apiError('not found');
res.apiResponse({
location: item
});
});
}
Current API output (truncated):
{
"locations": [
{
"_id": "53a47997ebe91d8a4a26d251",
"slug": "test-location",
"lastModified": "2014-06-20T20:19:14.484Z",
"commonName": "test location",
"__v": 3,
"url": "",
"tours": [
"53a47963ebe91d8a4a26d250"
],
"images": []
}
]
}
What I'm looking for:
{
"locations": [
{
"_id": "53a47997ebe91d8a4a26d251",
"slug": "test-location",
"lastModified": "2014-06-20T20:19:14.484Z",
"commonName": "test location",
"__v": 3,
"url": "",
"tours": [
{
"_id": "53a47963ebe91d8a4a26d250",
"title": "my test tour title",
"url": "url_to_audio_file"
}
],
"images": []
}
]
}
Anyone know if this is possible? Any help would be appreciated! Thanks!
It looks like you have setup your Location model to have a reference to the Tours, defined as an array of Tours. This means that when you store the Tour within your Location, you're not storing the data that represents that Tour, but instead an ID that references the Tour. When you perform the find operation, you're seeing that in the response that you send back to the client.
If this is the case, then you might want to take a look at Mongoose's populate function. This will take those references and populate them fully with the data that they contain.
So for instance, you can change your query to the following:
Location.model.find().populate('tours').exec(function(err, items) {
// items should now contain fully populated tours
}
Let me know if this isn't what you mean and I can try to help further.
The solution provided by #dylants is absolutely correct. However, for it to work you need to have tours declared as a Types.Relationship field in your Location list with the ref option set to Tour.
Check out the Keystone docs on Relationship Fields.
I included the many: true option in my example below, because I assumed this is a one-to-many relationship. If it isn't, you can discard it.
var keystone = require('keystone'),
Location = keystone.list('Location');
Location.add({
...
tours: { type: Types.Relationship, ref: 'Tour', many: true },
...
});
The List.relationship() method you mentioned is meant to be used only if you want a list of related documents to automatically appear in the Keystone Admin UI, and not to establish the actual relationship.
Hope this helps.

Resources