I have 2 models in my project, 1 is stores and the other is products, the stores has a reference to products like this:
produtos: [
{ type: mongoose.Schema.ObjectId, ref: 'Produto' }
]
and basicly at the moment i have a object like this:
{
"_id": "589715a3a2030f7bc143ed89",
"nome": "levis2",
"email": "filipecostaa10#gmail.com1",
"password": "1234",
"__v": 8,
"produtos": [
"58971695a2030f7bc143ed8a",
"589716d7a2030f7bc143ed8b",
"58971742a2030f7bc143ed8c",
"58971770a2030f7bc143ed8d",
"589717a1a2030f7bc143ed8e",
"58971848a2030f7bc143ed8f",
"589718f5a2030f7bc143ed90",
"58971937a2030f7bc143ed91"
],
"descricao": "No description for this store"
}
the array produtos has a lot of ids. Those ids are reference to the products; What i need to know now is how i can do a get request to get all the products with those ids, how do i send the request?
here is my router
router.get('/',function(req,res){
Loja.find(function(err,lojas){
if(!lojas){
return res.status(404).json({Error:"Loja nao encontrada"});
}
res.send(lojas);
}).populate("Produto");
})
Seems you are trying to get all stores with populated products field so:
router
.route('/')
.get(function(req, res) {
Loja
.find()
.populate('produtos')
.exec(function(err, lojas) {
if ( err ) {
return handleError(err);
}
res.json(lojas);
});
});
Related
Despite looking at many other posts I can't figure out what I'm doing wrong. I want to do a simple "count and group by", so I found out I need to use collection.aggregate....
Here is my [pubkey].ts where I execute the aggregation, basically I want to count each entry grouped by address sp I'd get something like :
{address1: 6},
{address2: 1},
...
import { connect } from '../../../utils/db'
import Raffles from '../../../utils/db/raffle'
export default async function handler(req, res) {
const { method } = req
const { pubkey } = req.query
await connect()
switch (method) {
case 'POST':
...
break
case 'GET':
try{
const ticket = await Raffles.aggregate([{
"$match": {
"address": pubkey
}
},{
"$count": { $sum: 1}
}])
res.status(201).json({ success: true, data: ticket })
} catch (error){
res.status(400).json({ success: false, data: error })
}
break
default:
res.status(400).json({ success: false })
break
}
}
I can't figure out how to do the summing part, if I replace "$count": "xxyz" I get a success but right now with "$count" : {$sum: 1} I get an error
Any ideas ?
If you use the $count stage, it only receives a string parameter for the name of the field, so your pipeline could be like this:
[
{
"$match": {
"address": pubkey
}
},
{
"$count": "total"
}
]
It filters the documents that match the address and then gets the count. If you want the count of documents grouped by address, you can use this $group stage in the pipeline (in this case $count is an aggregation accumulator, so it doesn't take any parameter):
[
{
$group: {
"_id": "$address",
"total": {
$count: {}
}
}
}
]
That should give you some results like this:
{_id: address1, total: 6}
{_id: address2, total: 1}
I am using redux with normlizr
after normalizing the object I got the following store structure:
{
posts: {
byId : {
"123":{..obj},
"124":{..obj}
}
},
comments: {
byId : {
"123":{..obj},
"124":{..obj}
}
},
users:{
byId : {
"123":{..obj},
"124":{..obj}
}
}
}
the ids are the same as the posts (post is the parent lets say)
so when I select all posts I got smth like :
{
posts : [
{
"id" : "123",
...data
"comment":"123",
"user": "123"
}
]
}
but I would like the data of comment and user also inside the posts array result instead of only id
how can I achieve that?
I made an http request and got back e.g the below json. I want to read the cars and the shoes objects into separate arrays at the time of the http request.
json
{
"id": 9,
"name": "Zlatan",
"cars": [
{
"type": "ford",
"year": "2019"
},
{
"type": "audi",
"year": "2017"
}
]
"shoes": [
{
"brand": "adidas",
"status": "old"
},
{
"brand": "timberland",
"status": "new"
}
]
}
comp.ts
cars = [];
shoes = [];
//......
getZlatan() {
return this.httpService.getInfo()
.subscribe( data => {
this.objZlatan = data; //this part holds the json obj above
this.cars ....//what to add here
this.shoes ....// here too.
} );
}
Or is there a cleaner way to load the arrays at http request?
Access the cars and shoes properties of the data with simple dot-notation. It might be ideal to check if the data returned is not null with if(condition here) and then perform your logic. If you have more objects and want to bring all cars and shoes under one array then you have to loop through.
getZlatan() {
return this.httpService.getInfo()
.subscribe(data => {
this.objZlatan = data;
this.cars = this.objZlatan.cars;
this.shoes = this.objZlatan.shoes;
});
}
Just use . and type names to access cars and shoes. Let me show an example:
return this.httpService.getInfo()
.subscribe( data => {
this.objZlatan = data; //this part holds the json obj above
this.cars = data.cars;
this.shoes =data.shoes;
} );
I have two Collections Category and Feeds.
Category
{
"_id": "ADFGFDF",
"title" : "title",
}
Feeds
{
"_id": "DFSAHT",
"feeds" : "ds sdsd sds",
"categoryId" : "catId"
}
I need to get the result like this:
{
"_id": "ADFGFDF",
"title" : "title",
"categoryId" : "DFSAHT"
"category" : {
"_id": "DFSAHT",
"feeds" : "ds sdsd sds",
}
}
I tried using publish-composite and here it's my code.
Server
Meteor.publishComposite('feedscateg', function () {
return {
find: function () {
return Category.find({});
},
children: [
{
find: function (cat) {
return Feeds.find({ categoryID: cat._id });
}
}
]
}
});
In client Angular i tried this:
$scope.feeds = $meteor.collection(Category).subscribe('feedscateg');
And I am confused with the view part also.
publishComposite do not modify collection data, it will load Feeds and Category separately. If you want to get category of feed item just select it from client db.
$scope.getFeedCategory = function (feedItem) {
Category.findOne({'_id': feedItem.categoryId});
};
In my app I have Students who can Enroll in Classes.
An Enrollment records the start and end dates along with a reference to which Class.
The Class has details like a class name and description.
Student (1) - (N) Enrollment (1) - (1) Class
Therefore
Student (1) - (N) Class
This is what I would like the object to look like.
{
"studentId": 1,
"name": "Henrietta",
"enrolledClasses": [
{
"enrollmentId": 12,
"startDate": "2015-08-06T17:43:14.000Z",
"endDate": null,
"class":
{
"classId": 15,
"name": "Algebra",
"description": "..."
}
},
"enrollmentId": 13,
"startDate": "2015-08-06T17:44:14.000Z",
"endDate": null,
"class":
{
"classId": 29,
"name": "Physics",
"description": "..."
}
}
}
But my RESTful API cannot (easily) output the full nested structure of the relationship because it's ORM can't do Many to Many with Through relationships. So I get the student and their multiple enrollments, but only a reference to the class for each, not the details. And I need to show the details, not just an Id.
I could wait for the student object to be available and then use the references to make additional calls to the API for each classId to get details, but am not sure how, or even if, to then integrate it with the student object.
This is what I have so far.
function findOne() {
vm.student = StudentsResource.get({
studentId: $stateParams.studentId
});
};
This is what I get back from my API
{
"studentId": 1,
"name": "Henrietta",
"enrolledClasses": [
{
"enrollmentId": 12,
"startDate": "2015-08-06T17:43:14.000Z",
"endDate": null,
"class": 15
},
"enrollmentId": 13,
"startDate": "2015-08-06T17:44:14.000Z",
"endDate": null,
"class": 29
}
}
And for the class details I can them one at a time but haven't figured out how to wait until the student object is available to push them into it. Nor how to properly push them...
{
"classId": 15,
"name": "Algebra",
"description": "..."
}
{
"classId": 29,
"name": "Physics",
"description": "..."
}
Question
Is it good practice to combine the student and class(es) details through the enrollments, as one object?
If so, whats the most clear way to go about it?
If not, what is another effective approach?
Keep in mind that the app will allow changes to the student details and enrollments, but should not allow changes to the details of the class name or description. So if Angular were to send a PUT for the object, it should not try to send the details of any class, only the reference. This would be enforced server side to protect the data, but to avoid errors, the client shouldn't try.
For background, I'm using SailsJS and PostgreSQL for the backend API.
So basically on the Sailsjs side you should override your findOne function in your StudentController.js. This is assuming you are using blueprints.
// StudentController.js
module.exports = {
findOne: function(req, res) {
Student.findOne(req.param('id')).populate('enrollments').then(function(student){
var studentClasses = Class.find({
id: _.pluck(student.enrollments, 'class')
}).then(function (classes) {
return classes
})
return [student, classes]
}).spread(function(student, classes){
var classes = _.indexBy(classes, 'id')
student.enrollments = _.map(student.enrollments, function(enrollment){
enrollment.class = classes[enrollment.class]
return enrollment
})
res.json(200, student)
}).catch(function(err){
if (err) return res.serverError(err)
})
}
}
// Student.js
module.exports = {
attributes: {
enrollments: {
collection: 'enrollment',
via: 'student'
}
// Rest of the attributes..
}
}
// Enrollment.js
module.exports = {
attributes: {
student: {
model: 'student'
}
class: {
model: 'class'
}
// Rest of the attributes...
}
}
// Class.js
module.exports: {
attributes: {
enrollments: {
collection: 'enrollment',
via: 'class'
}
// Rest of the attrubutes
}
}
Explanation:
1. the _.pluck function using Lo-dash retuns an array of classIds and we find all of the classes that we wanted populated. Then we use the promise chain .spread(), create an array indexed by classid and map the classIds to the actual class instances we wanted populated into the enrollments on the student returned from Student.findOne().
2. Return the student with enrollments deep populated with the proper class.
source: Sails.js populate nested associations