So this is my method for getting all posts related to their corresponding topics.
const moment = require('moment');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const Post = require('../models/Post');
let posts = {
getPosts: function(req, res) {
return Post.find({ topicId: req.params._id })
.then(function(result) {
console.log('------------------------------------');
console.log('Headed to the Client: ', result);
console.log('------------------------------------');
res.json(result);
})
.catch(function(error) {
console.log('Nope! Nerd!');
return Promise.reject(error);
})
}
}
the result comes out like so:
[ { _id: 58deac2223b5b92ce45bdfac,
topicId: '58dd6f541919c541dbf9632d',
parentId: null,
content: '1 Post',
author: 'Bob',
createdAt: 2017-03-31T19:21:06.698Z,
isAnon: false,
__v: 0,
comments: [],
isArchieved: false,
isParent: true },
{ _id: 58deac2c23b5b92ce45bdfad,
topicId: '58dd6f541919c541dbf9632d',
parentId: null,
content: '2 Post',
author: 'Bob',
createdAt: 2017-03-31T19:21:16.622Z,
isAnon: false,
__v: 0,
comments: [],
isArchieved: false,
isParent: true },
{ _id: 58deac3c23b5b92ce45bdfae,
topicId: '58dd6f541919c541dbf9632d',
parentId: null,
content: '3 Post',
author: 'Bob',
createdAt: 2017-03-31T19:21:32.682Z,
isAnon: false,
__v: 0,
comments: [],
isArchieved: false,
isParent: true },
{ _id: 58deac5e23b5b92ce45bdfaf,
topicId: '58dd6f541919c541dbf9632d',
parentId: '58deac3c23b5b92ce45bdfae',
content: '1 Comment',
author: 'Kat',
createdAt: 2017-03-31T19:22:06.974Z,
isAnon: false,
__v: 0,
comments: [],
isArchieved: false,
isParent: false },
{ _id: 58deac6c23b5b92ce45bdfb0,
topicId: '58dd6f541919c541dbf9632d',
parentId: '58deac2223b5b92ce45bdfac',
content: '2 Comment',
author: 'Dave',
createdAt: 2017-03-31T19:22:20.071Z,
isAnon: false,
__v: 0,
comments: [],
isArchieved: false,
isParent: false },
{ _id: 58deac7a23b5b92ce45bdfb1,
topicId: '58dd6f541919c541dbf9632d',
parentId: '58deac2c23b5b92ce45bdfad',
content: '4 Comment',
author: 'Bob',
createdAt: 2017-03-31T19:22:34.865Z,
isAnon: false,
__v: 0,
comments: [],
isArchieved: false,
isParent: false } ]
I am getting stuck because I need to modify this list after it comes out of the database to grab the posts with parentIds and push them into their corresponding parents'comments array.
so the the result actually sent to the client looks like this:
[{
_id: 58deac2223b5b92ce45bdfa',
topicId: '58dd6f541919c541dbf9632d',
parentId: null,
content: '1 Post',
author: 'Bob',
isAnon: false,
__v: 0,
comments: [{
_id: 58deac6c23b5b92ce45bdfb0,
topicId: '58dd6f541919c541dbf9632d',
parentId: '58deac2223b5b92ce45bdfac',
content: '2 Comment',
author: 'Dave',
isAnon: false,
__v: 0,
comments: [],
isArchieved: false,
isParent: false
}],
isArchieved: false,
isParent: true
},
{
_id: 58deac2c23b5b92ce45bdfad,
topicId: '58dd6f541919c541dbf9632d',
parentId: null,
content: '2 Post',
author: 'Bob',
isAnon: false,
__v: 0,
comments: [{
_id: 58deac7a23b5b92ce45bdfb1,
topicId: '58dd6f541919c541dbf9632d',
parentId: '58deac2c23b5b92ce45bdfad',
content: '4 Comment',
author: 'Bob',
isAnon: false,
__v: 0,
comments: [],
isArchieved: false,
isParent: false
}],
isArchieved: false,
isParent: true
},
{
_id: 58deac3c23b5b92ce45bdfae,
topicId: '58dd6f541919c541dbf9632d',
parentId: null,
content: '3 Post',
author: 'Bob',
isAnon: false,
__v: 0,
comments: [{
_id: 58deac5e23b5b92ce45bdfaf,
topicId: '58dd6f541919c541dbf9632d',
parentId: '58deac3c23b5b92ce45bdfae',
content: '1 Comment',
author: 'Kat',
isAnon: false,
__v: 0,
comments: [],
isArchieved: false,
isParent: false
}],
isArchieved: false,
isParent: true
}
]
I know I need to recurse through the array but I'm stumped on the logic in between. Any help would be appreciated. Thank you so much.
You could use an object for collecting all nodes and append found children to the comments property. Get the nodes with parentId === null as root noded.
This approach works for unsorted data for any depth and use a single loop to get the nested result.
var data = [{ _id: '58deac2223b5b92ce45bdfac', topicId: '58dd6f541919c541dbf9632d', parentId: null, content: '1 Post', author: 'Bob', createdAt: '2017-03-31T19:21:06.698Z', isAnon: false, __v: 0, comments: [], isArchieved: false, isParent: true }, { _id: '58deac2c23b5b92ce45bdfad', topicId: '58dd6f541919c541dbf9632d', parentId: null, content: '2 Post', author: 'Bob', createdAt: '2017-03-31T19:21:16.622Z', isAnon: false, __v: 0, comments: [], isArchieved: false, isParent: true }, { _id: '58deac3c23b5b92ce45bdfae', topicId: '58dd6f541919c541dbf9632d', parentId: null, content: '3 Post', author: 'Bob', createdAt: '2017-03-31T19:21:32.682Z', isAnon: false, __v: 0, comments: [], isArchieved: false, isParent: true }, { _id: '58deac5e23b5b92ce45bdfaf', topicId: '58dd6f541919c541dbf9632d', parentId: '58deac3c23b5b92ce45bdfae', content: '1 Comment', author: 'Kat', createdAt: '2017-03-31T19:22:06.974Z', isAnon: false, __v: 0, comments: [], isArchieved: false, isParent: false }, { _id: '58deac6c23b5b92ce45bdfb0', topicId: '58dd6f541919c541dbf9632d', parentId: '58deac2223b5b92ce45bdfac', content: '2 Comment', author: 'Dave', createdAt: '2017-03-31T19:22:20.071Z', isAnon: false, __v: 0, comments: [], isArchieved: false, isParent: false }, { _id: '58deac7a23b5b92ce45bdfb1', topicId: '58dd6f541919c541dbf9632d', parentId: '58deac2c23b5b92ce45bdfad', content: '4 Comment', author: 'Bob', createdAt: '2017-03-31T19:22:34.865Z', isAnon: false, __v: 0, comments: [], isArchieved: false, isParent: false }],
tree = function (data, root) {
var r = [],
o = {};
data.forEach(function (a) {
a.comments = (o[a._id] && o[a._id].comments || []).concat();
o[a._id] = a;
if (a.parentId === root) {
r.push(a);
} else {
o[a.parentId] = o[a.parentId] || {};
o[a.parentId].comments = o[a.parentId].comments || [];
o[a.parentId].comments.push(a);
}
});
return r;
}(data, null);
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Related
Hi I have following model of a document in mongodb
Schema is
const ProductionsSchema=new Schema({
name: {type: String, required: true, unique: true},
isActive: {type: Boolean, default: true},
locations: [{
name: {type: String},
isActive : {type: Boolean, default: false}
}],
trackno: {type: String}
})
Productions:[{
_id: 125,
name: 'John Smith',
locations: [{ name: 'Boston', isActive: true}]
isActive: true,
trackno: 2123
},
{
_id: 126,
name: 'Moe Adam',
locations: [{ name: 'Chicago', isActive: true}]
isActive: true,
trackno: 5663
},
{
_id: 126,
name: 'Henry Noel',
locations: [{ name: 'Houston', isActive: false}]
isActive: true,
trackno: 4552
},
{
_id: 128,
name: 'Tim Johnson',
locations: [{ name: 'Denver', isActive: true}]
isActive: false,
trackno: 6672
}
]
I am trying to find list of with both isActive true
Productions.find({"isActive" : true , "locations.isActive": true}, (err, list)=>{
if(err){
callback(err);
}
callback(null, list)
})
I am trying to write query so both isActive are true. In above sample data only first two records should be in the answer. But I keep getting all the records even ones with 'false' I even tried $elemMatch on locations.isActive still didnt work.
Please let me know how I can fix this so that I only get result that contains only true values for both isActive.
As the original comment explained, the only query conditions you need are:
{ isActive: true, "locations.isActive": true }
This is a basic AND condition, and you don't need any special operators just to verify a condition is met on a single property anywhere in an array, which is all you are asking.
Since this works exactly as expected, I can only think to show you a full working listing to use as a basis to work out what you are doing differently thus causing you to not get the same result as what is expected.
const { Schema } = mongoose = require('mongoose');
const uri = 'mongodb://localhost:27017/productions';
const opts = { useNewUrlParser: true };
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
mongoose.set('debug', true);
const productionSchema = new Schema({
name: String,
isActive: { type: Boolean, default: true },
locations: [{
name: String,
isActive: { type: Boolean, default: false }
}],
trackno: Number
})
const Production = mongoose.model('Production', productionSchema);
const data =
[
{
name: 'John Smith',
locations: [{ name: 'Boston', isActive: true}],
isActive: true,
trackno: 2123
},
{
name: 'Moe Adam',
locations: [{ name: 'Chicago', isActive: true}],
isActive: true,
trackno: 5663
},
{
name: 'Henry Noel',
locations: [{ name: 'Houston', isActive: false}],
isActive: true,
trackno: 4552
},
{
name: 'Tim Johnson',
locations: [{ name: 'Denver', isActive: true}],
isActive: false,
trackno: 6672
}
];
const log = data => console.log(JSON.stringify(data, undefined, 2));
(async function() {
try {
const conn = await mongoose.connect(uri, opts);
// clean data
await Promise.all(
Object.entries(conn.models).map(([k, m]) => m.deleteMany())
);
// set up
await Production.insertMany(data);
// Query
let query = { isActive: true, "locations.isActive": true };
let results = await Production.find(query);
log(results);
} catch(e) {
console.error(e)
} finally {
mongoose.disconnect()
}
})()
Which outputs the two expected documents:
Mongoose: productions.deleteMany({}, {})
Mongoose: productions.insertMany([ { isActive: true, _id: 5c7f7e9367daed19d6773e9b, name: 'John Smith', locations: [ { isActive: true, _id: 5c7f7e9367daed19d6773e9c, name: 'Boston' } ], trackno: 2123, __v: 0 }, { isActive: true, _id: 5c7f7e9367daed19d6773e9d, name: 'Moe Adam', locations: [ { isActive: true, _id: 5c7f7e9367daed19d6773e9e, name: 'Chicago' } ], trackno: 5663, __v: 0 }, { isActive: true, _id: 5c7f7e9367daed19d6773e9f, name: 'Henry Noel', locations: [ { isActive: false, _id: 5c7f7e9367daed19d6773ea0, name: 'Houston' } ], trackno: 4552, __v: 0 }, { isActive: false, _id: 5c7f7e9367daed19d6773ea1, name: 'Tim Johnson', locations: [ { isActive: true, _id: 5c7f7e9367daed19d6773ea2, name: 'Denver' } ], trackno: 6672, __v: 0 } ], {})
Mongoose: productions.find({ isActive: true, 'locations.isActive': true }, { projection: {} })
[
{
"isActive": true,
"_id": "5c7f7e9367daed19d6773e9b",
"name": "John Smith",
"locations": [
{
"isActive": true,
"_id": "5c7f7e9367daed19d6773e9c",
"name": "Boston"
}
],
"trackno": 2123,
"__v": 0
},
{
"isActive": true,
"_id": "5c7f7e9367daed19d6773e9d",
"name": "Moe Adam",
"locations": [
{
"isActive": true,
"_id": "5c7f7e9367daed19d6773e9e",
"name": "Chicago"
}
],
"trackno": 5663,
"__v": 0
}
]
I've object of array, each object has a key 'id', and there is another array whoes elements are actually id of first array, so i want to filter out the objects from 1st array whoes ids are matched from 2nd array
const categories = [
{ id: 1,
name: 'Permaculture',
active: false,
createdAt: '2018-06-18T11:38:41.000Z',
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 2,
name: 'Food Forest',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 3,
name: 'Community Supported Farming (CSA)',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 4,
name: 'Urban Farming',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 5,
name: 'Roof Farming',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 6,
name: 'Roof Gardening',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 7,
name: 'Gardening',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 8,
name: 'Indoor Plantation',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 9,
name: 'Soil Culture',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 10,
name: 'Tropical Farming',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 11,
name: 'Greenhouse',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 12,
name: 'Hobby Farming',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 13,
name: 'WWOOF',
active: false,
createdAt: "2018-06-18T11:44:56.000Z",
updatedAt: "2018-06-18T11:44:56.000Z" },
{ id: 14,
name: 'Organic Farming',
active: false,
createdAt: "2018-06-18T11:44:56.000Z",
updatedAt: "2018-06-18T11:44:56.000Z" }
];
const ids = [1, 4, 2];
const expected_res = [
{
id: 1,
name: "Permaculture"
},
{
id: 4,
name: "Urban Farming"
},
{
id: 2,
name: "Food Forest"
}
]
This will filter as per your condition but doesn't keep the ordering of the id though.
const categories = [{
id: 1,
name: 'Permaculture',
active: false,
createdAt: '2018-06-18T11:38:41.000Z',
updatedAt: "2018-06-18T11:38:41.000Z"
},
{
id: 2,
name: 'Food Forest',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z"
},
{
id: 3,
name: 'Community Supported Farming (CSA)',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z"
},
{
id: 4,
name: 'Urban Farming',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z"
},
{
id: 5,
name: 'Roof Farming',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z"
},
{
id: 6,
name: 'Roof Gardening',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z"
},
{
id: 7,
name: 'Gardening',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z"
},
{
id: 8,
name: 'Indoor Plantation',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z"
},
{
id: 9,
name: 'Soil Culture',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z"
},
{
id: 10,
name: 'Tropical Farming',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z"
},
{
id: 11,
name: 'Greenhouse',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z"
},
{
id: 12,
name: 'Hobby Farming',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z"
},
{
id: 13,
name: 'WWOOF',
active: false,
createdAt: "2018-06-18T11:44:56.000Z",
updatedAt: "2018-06-18T11:44:56.000Z"
},
{
id: 14,
name: 'Organic Farming',
active: false,
createdAt: "2018-06-18T11:44:56.000Z",
updatedAt: "2018-06-18T11:44:56.000Z"
}
];
const ids = [1, 4, 2];
console.log(categories.filter(x => ids.includes(x.id)))
Use array.filter Filter will check if the objects id is inside the id array or not. If it is present it will insert it into the array. After iterating over all the elements it will return the array.
const categories = [
{ id: 1,
name: 'Permaculture',
active: false,
createdAt: '2018-06-18T11:38:41.000Z',
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 2,
name: 'Food Forest',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 3,
name: 'Community Supported Farming (CSA)',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 4,
name: 'Urban Farming',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 5,
name: 'Roof Farming',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 6,
name: 'Roof Gardening',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 7,
name: 'Gardening',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 8,
name: 'Indoor Plantation',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 9,
name: 'Soil Culture',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 10,
name: 'Tropical Farming',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 11,
name: 'Greenhouse',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 12,
name: 'Hobby Farming',
active: false,
createdAt: "2018-06-18T11:38:41.000Z",
updatedAt: "2018-06-18T11:38:41.000Z" },
{ id: 13,
name: 'WWOOF',
active: false,
createdAt: "2018-06-18T11:44:56.000Z",
updatedAt: "2018-06-18T11:44:56.000Z" },
{ id: 14,
name: 'Organic Farming',
active: false,
createdAt: "2018-06-18T11:44:56.000Z",
updatedAt: "2018-06-18T11:44:56.000Z" }
];
const ids = [1, 4, 2];
console.log(categories.filter((e)=>ids.indexOf(e.id)!=-1?e:false))
You can use .reduce to achieve this as you want only the id and name in your result. If the current object's id is in the array of ids, then you can add it to the acc (accumulator)
const categories = [{id:1,name:"Permaculture",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:2,name:"Food Forest",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:3,name:"Community Supported Farming (CSA)",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:4,name:"Urban Farming",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:5,name:"Roof Farming",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:6,name:"Roof Gardening",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:7,name:"Gardening",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:8,name:"Indoor Plantation",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:9,name:"Soil Culture",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:10,name:"Tropical Farming",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:11,name:"Greenhouse",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:12,name:"Hobby Farming",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:13,name:"WWOOF",active:!1,createdAt:"2018-06-18T11:44:56.000Z",updatedAt:"2018-06-18T11:44:56.000Z"},{id:14,name:"Organic Farming",active:!1,createdAt:"2018-06-18T11:44:56.000Z",updatedAt:"2018-06-18T11:44:56.000Z"}],
ids = [1, 4, 2],
res = categories.reduce((acc, {id, name}) => ids.includes(id) ? [...acc, {id, name}] : acc, []);
console.log(res);
However, if you care about the order in which your objects appear, you can use .map on the above output to map the number to it's a corresponding object where the number equals the id of the object (using .find())
const categories = [{id:1,name:"Permaculture",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:2,name:"Food Forest",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:3,name:"Community Supported Farming (CSA)",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:4,name:"Urban Farming",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:5,name:"Roof Farming",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:6,name:"Roof Gardening",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:7,name:"Gardening",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:8,name:"Indoor Plantation",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:9,name:"Soil Culture",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:10,name:"Tropical Farming",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:11,name:"Greenhouse",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:12,name:"Hobby Farming",active:!1,createdAt:"2018-06-18T11:38:41.000Z",updatedAt:"2018-06-18T11:38:41.000Z"},{id:13,name:"WWOOF",active:!1,createdAt:"2018-06-18T11:44:56.000Z",updatedAt:"2018-06-18T11:44:56.000Z"},{id:14,name:"Organic Farming",active:!1,createdAt:"2018-06-18T11:44:56.000Z",updatedAt:"2018-06-18T11:44:56.000Z"}],
ids = [1, 4, 2],
res = ids.map(num => categories.reduce((acc, {id, name}) => ids.includes(id) ? [...acc, {id, name}] : acc, []).find(({id}) => num === id));
console.log(res);
This question already has answers here:
Querying after populate in Mongoose
(6 answers)
Aggregation filter after $lookup
(1 answer)
Retrieve only the queried element in an object array in MongoDB collection
(18 answers)
Closed 4 years ago.
I have two models, Game and User. Game model is
const GameSchema = new Schema({
date: String,
time: String,
duration: Number, // minutes
location: [{ type: Schema.Types.ObjectId, ref: 'Court' }],
players_needed: Number,
max_players: Number,
level: Number,
players_list: [{ type: Schema.Types.ObjectId, ref: 'User' }], // players_list: [{ type: String }],
players_status: [{ playerId: String, status: String }], // status -joined or evaluted
postGameEvaluation: [{ playerId: String, evaluations: { } }],
author: { type: Schema.Types.ObjectId, ref: 'User' },
});
and User model is
const UserSchema = new Schema({
email: { type: String, unique: true, lowercase: true },
password: { type: String },
handle: { type: String }, // handle: { type: String, unique: true, lowercase: true },
games: [{ type: Schema.Types.ObjectId, ref: 'Post' }], // games and status
});
And I am trying to check if a User is already in the players_list of a Game using this
if (req.body.players_list.filter((e) => { return e._id === req.user._id; }).length > 0) {
.....
However, even when the User is already in the game, the if statement fails to check it. For example, here are two instances of a Game and User object where the if statement fails. This is the Game object
{ location: [],
players_list:
[ { games: [],
_id: '5b0cb9ff4a9c6a536d075f48',
email: 'efafesfse',
password: '$2a$10$bo1q0udXhL5ZnA9PMUZX4ufR0w0tcL5TmDARqAT5RpqfXheVtK3v2',
handle: 'FSEFSEFSE',
__v: 0,
id: '5b0cb9ff4a9c6a536d075f48' },
{ games: [Array],
_id: '5b0cba164a9c6a536d075f4b',
email: 'poi',
password: '$2a$10$sk.d5npeUMz0H9aQ6TKVzOir1j54UuXtdtQPIrxbKkwzPP07ODW/y',
handle: 'POI',
__v: 0,
id: '5b0cba164a9c6a536d075f4b' },
{ games: [Array],
_id: '5b0cba164a9c6a536d075f4b',
email: 'poi',
password: '$2a$10$sk.d5npeUMz0H9aQ6TKVzOir1j54UuXtdtQPIrxbKkwzPP07ODW/y',
handle: 'POI',
__v: 0,
id: '5b0cba164a9c6a536d075f4b' },
{ games: [Array],
_id: '5b0cbcd74a9c6a536d075f4e',
email: 'bv',
password: '$2a$10$BTvyzp9EnauZkODsg5010e/OUafNmjRbmAvJ33RslHbT.qiWTY4WC',
handle: 'BV',
__v: 0,
id: '5b0cbcd74a9c6a536d075f4e' } ],
_id: '5b0cba094a9c6a536d075f49',
players_status:
[ { _id: '5b0cba094a9c6a536d075f4a',
playerId: '5b0cb9ff4a9c6a536d075f48',
status: 'Joined' } ],
postGameEvaluation: [],
date: 'VVVVV',
time: 'VVVVVVV',
duration: 4,
players_needed: 4,
max_players: 4,
level: 4,
author:
{ games: [],
_id: '5b0cb9ff4a9c6a536d075f48',
email: 'efafesfse',
password: '$2a$10$bo1q0udXhL5ZnA9PMUZX4ufR0w0tcL5TmDARqAT5RpqfXheVtK3v2',
handle: 'FSEFSEFSE',
__v: 0,
id: '5b0cb9ff4a9c6a536d075f48' },
__v: 0 }
And here is the User object that is already in the players_list of the game but the if statement fails to check for it
{ games: [ 5b0cba094a9c6a536d075f49 ],
_id: 5b0cbcd74a9c6a536d075f4e,
email: 'bv',
password: '$2a$10$BTvyzp9EnauZkODsg5010e/OUafNmjRbmAvJ33RslHbT.qiWTY4WC',
handle: 'BV',
__v: 0 }
I am trying to add an User object to my Game object's field "players_list", which is a list of User objects. This is what my Game object looks like:
{ players_list:
[ { games: [Array],
_id: '5b0e112ff13033792f08566f',
email: 'c',
password: '$2a$10$iWOBvVf4KAPwbH7zDczfYeI5iXI721jQ7bN1juJ4Us3R.Lqetmhfu',
handle: 'C',
__v: 0,
id: '5b0e112ff13033792f08566f' } ],
_id: '5b0e181aeb766e7bfaf2fb09',
players_status:
[ { _id: '5b0e181aeb766e7bfaf2fb0a',
playerId: '5b0e112ff13033792f08566f',
status: 'Joined' } ],
postGameEvaluation: [],
date: 'QQQQ',
time: 'QQQQ',
duration: 4,
players_needed: 4,
max_players: 4,
level: 4,
author:
{ games:
[ '5b0e13e69d35007a147578da',
'5b0e15b4b117987b00d68cb4',
'5b0e181aeb766e7bfaf2fb09' ],
_id: '5b0e112ff13033792f08566f',
email: 'c',
password: '$2a$10$iWOBvVf4KAPwbH7zDczfYeI5iXI721jQ7bN1juJ4Us3R.Lqetmhfu',
handle: 'C',
__v: 0,
id: '5b0e112ff13033792f08566f' },
__v: 0 }
and this is what my User objet looks like
{ games: [],
_id: 5b0e1820eb766e7bfaf2fb0b,
email: 'f',
password: '$2a$10$JmS.9axW8batMUKzE7OQx.GShdNDt09eArXfYGoI/DUWEKVwAn5ju',
handle: 'F',
__v: 0 }
I then run req.body.players_list.push(req.user) to add the User object to the player_list field of the Game object. This is what by req.body looks like after adding the User object:
{ players_list:
[ { games: [Array],
_id: '5b0e112ff13033792f08566f',
email: 'c',
password: '$2a$10$iWOBvVf4KAPwbH7zDczfYeI5iXI721jQ7bN1juJ4Us3R.Lqetmhfu',
handle: 'C',
__v: 0,
id: '5b0e112ff13033792f08566f' },
{ games: [],
_id: 5b0e1820eb766e7bfaf2fb0b,
email: 'f',
password: '$2a$10$JmS.9axW8batMUKzE7OQx.GShdNDt09eArXfYGoI/DUWEKVwAn5ju',
handle: 'F',
__v: 0 } ],
_id: '5b0e181aeb766e7bfaf2fb09',
players_status:
[ { _id: '5b0e181aeb766e7bfaf2fb0a',
playerId: '5b0e112ff13033792f08566f',
status: 'Joined' } ],
postGameEvaluation: [],
date: 'QQQQ',
time: 'QQQQ',
duration: 4,
players_needed: 4,
max_players: 4,
level: 4,
author:
{ games:
[ '5b0e13e69d35007a147578da',
'5b0e15b4b117987b00d68cb4',
'5b0e181aeb766e7bfaf2fb09' ],
_id: '5b0e112ff13033792f08566f',
email: 'c',
password: '$2a$10$iWOBvVf4KAPwbH7zDczfYeI5iXI721jQ7bN1juJ4Us3R.Lqetmhfu',
handle: 'C',
__v: 0,
id: '5b0e112ff13033792f08566f' },
__v: 0 }
So, I then update the Game object in mongo with Post.findByIdAndUpdate(req.params.id, req.body).then((result) => {..., but the result doesn't contain the new User. This is what my result looks like
{ players_list: [ 5b0e112ff13033792f08566f ],
_id: 5b0e181aeb766e7bfaf2fb09,
players_status:
[ { _id: 5b0e181aeb766e7bfaf2fb0a,
playerId: '5b0e112ff13033792f08566f',
status: 'Joined' } ],
postGameEvaluation: [],
date: 'QQQQ',
time: 'QQQQ',
duration: 4,
players_needed: 4,
max_players: 4,
level: 4,
author: 5b0e112ff13033792f08566f,
__v: 0 }
The strange thing is that if I leave my current React Component, and then go back into it (thus triggering fetchUser and fetchGame), then the Game fetched does have the new User in its players_list. Does this happen because the mongo update function is asynchronous? Even so, I thought that the .then((result) => { in Post.findByIdAndUpdate(req.params.id, req.body).then((result) => { made sure that Post.findByIdAndUpdate completed first before continuing
If you look at the docs: http://mongoosejs.com/docs/api.html#findbyidandupdate_findByIdAndUpdate you'll notice that findByIdAndUpdate returns the original object, not the updated doc. You have to pass in {new: true} as options for it to resolve with the updated object.
I have this code into my app that returns some job feed in json format:
My code looks as below:
JobFeed.find().sort('-created').exec(function (err, feeds) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
_.forEach(feeds, function (row, key) {
console.log(row.data.title); // showing undefined
});
res.jsonp(feeds);
}
});
and the json looks like below:
{ data:
{ isSaved: null,
client:
{ lastContractTitle: null,
feedbackText: '4.78 Stars, based on 13 feedbacks',
paymentVerificationStatus: 1,
lastContractPlatform: null,
totalFeedback: 4.7819242373,
location: [Object],
lastContractRid: 0,
edcUserId: 3728985,
totalReviews: 13,
companyRid: 0,
spentTier: '$7,500+',
companyName: null },
amount: { amount: 0, currencyCode: 'USD' },
createdOn: '2016-10-13T06:30:54+00:00',
skills: [ [Object], [Object], [Object], [Object] ],
enterpriseJob: false,
ciphertext: '~01026b31d972ed826b',
proposalsTier: null,
description: 'Hello! We\'re currently searching for a developer with',
category2: 'Web, Mobile & Software Dev',
type: 2,
tierText: 'Intermediate ($$)',
relevance:
{ hoursInactive: 0,
id: 208660674,
publishTime: '1476340265000',
recommendedEffectiveCandidates: 2,
effectiveCandidates: 3,
uniqueImpressions: 0 },
isApplied: null,
engagement: '30+ hrs/week',
recno: 208660674,
title: 'Server-side and Client-side Game Developer for Indie MMO',
freelancersToHire: 0,
maxAmount: { amount: 0, currencyCode: 'USD' },
duration: 'More than 6 months',
subcategory2: 'Game Development',
sticky: false,
stickyLabel: '',
feedback: null },
id: 57ffcdbf717ca50cf0b4cbc1 }
{ data:
{ isSaved: null,
client:
{ lastContractTitle: null,
feedbackText: 'No feedback yet',
paymentVerificationStatus: 1,
lastContractPlatform: null,
totalFeedback: 0,
location: [Object],
lastContractRid: 0,
edcUserId: 0,
totalReviews: 0,
companyRid: 0,
spentTier: '$100+',
companyName: null },
amount: { amount: 0, currencyCode: 'USD' },
createdOn: '2016-10-13T06:30:51+00:00',
skills: [ [Object], [Object], [Object] ],
enterpriseJob: false,
ciphertext: '~01c59efb9135ed91d0',
proposalsTier: null,
description: 'Hello! We\'re currently searching for a developer with',
category2: 'Web, Mobile & Software Dev',
type: 2,
tierText: 'Entry Level ($)',
relevance:
{ hoursInactive: 0,
id: 208660673,
publishTime: '1476340266000',
recommendedEffectiveCandidates: 18,
effectiveCandidates: 74,
uniqueImpressions: 0 },
isApplied: null,
engagement: 'Less than 10 hrs/week',
recno: 208660673,
title: 'Wordpress & Stripe developer',
freelancersToHire: 0,
maxAmount: { amount: 0, currencyCode: 'USD' },
duration: 'More than 6 months',
subcategory2: 'Web Development',
sticky: false,
stickyLabel: '',
feedback: null },
id: 57ffcdbf717ca50cf0b4cbc2 }
{ data:
{ isSaved: null,
client:
{ lastContractTitle: null,
feedbackText: 'No feedback yet',
paymentVerificationStatus: 5,
lastContractPlatform: null,
totalFeedback: 0,
location: [Object],
lastContractRid: 0,
edcUserId: 0,
totalReviews: 0,
companyRid: 0,
spentTier: 'Less than $100',
companyName: null },
amount: { amount: 2000, currencyCode: 'USD' },
createdOn: '2016-10-13T06:30:18+00:00',
skills: [ [Object], [Object] ],
enterpriseJob: false,
ciphertext: '~0101449f91585e8e16',
proposalsTier: null,
description: 'I need a Christmas card app before 15th Dec.n',
category2: 'Web, Mobile & Software Dev',
type: 1,
tierText: 'Intermediate ($$)',
relevance:
{ hoursInactive: 0,
id: 208660669,
publishTime: '1476340233000',
recommendedEffectiveCandidates: 7,
effectiveCandidates: 52,
uniqueImpressions: 0 },
isApplied: null,
engagement: null,
recno: 208660669,
title: 'Christmas Card iPhone App',
freelancersToHire: 0,
maxAmount: { amount: 0, currencyCode: 'USD' },
duration: null,
subcategory2: 'Mobile Development',
sticky: false,
stickyLabel: '',
feedback: null },
id: 57ffcdbf717ca50cf0b4cbc3 }
{ data:
{ isSaved: null,
client:
{ lastContractTitle: null,
feedbackText: '4.88 Stars, based on 102 feedbacks',
paymentVerificationStatus: 1,
lastContractPlatform: null,
totalFeedback: 4.8843944128,
location: [Object],
lastContractRid: 0,
edcUserId: 0,
totalReviews: 102,
companyRid: 0,
spentTier: '$25,000+',
companyName: null },
amount: { amount: 100, currencyCode: 'USD' },
createdOn: '2016-10-13T06:30:00+00:00',
skills:
[ [Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object] ],
enterpriseJob: false,
ciphertext: '~01a04eab3b05372652',
proposalsTier: null,
description: 'Hello! We\'re currently searching for a developer with',
category2: 'Writing',
type: 1,
tierText: 'Entry Level ($)',
relevance:
{ hoursInactive: 0,
id: 208660668,
publishTime: '1476340202000',
recommendedEffectiveCandidates: 2,
effectiveCandidates: 6,
uniqueImpressions: 0 },
isApplied: null,
engagement: null,
recno: 208660668,
title: 'Filipino Blog/Content Writers For a Filipino Site (Using WordPress)',
freelancersToHire: 3,
maxAmount: { amount: 0, currencyCode: 'USD' },
duration: null,
subcategory2: 'Article & Blog Writing',
sticky: false,
stickyLabel: '',
feedback: null },
id: 57ffcdbf717ca50cf0b4cbc4 }
The foreach that I have, seems to iterate through each of items, but there is no way I can get the title for each item. Any Help?
I'm not really sure what you're trying to do, but something like this should work if the data is indeed what you have on your comments:
feeds.forEach(function(feed){
console.log(feed.data.title);
});
If you want faster performance, use the regular for loop. I tested this out on my project. Let me know if this doesn't work.