I'm building a "Test" system. each test has some questions.
Each question has answers.
I'm getting a JSON to create the question from another server as:
{
requestType: 'CreateNewQuestion',
questionId: 17447,
subject: "Math",
subsubject: "Heshbon",
questionText: "1+4 Equels?",
answers: [{text : "2",rightAnswer : false},
{text : "35",rightAnswer : false},
{text : "5",rightAnswer : true},
{text : "9",rightAnswer : false}]
}
I built 2 Schemas:
module.exports = mongoose.model('Answer' ,
{
text: String,
rightAnswer: Boolean
}
);
And
module.exports = mongoose.model('Question' ,
{
questionId: Number,
subject: String,
subsubject: String,
questionText: String,
answerTimeAvg: Number,
fastestAnswer: Number,
answers: [{ type : mongoose.Types.ObjectId, ref: 'Answer' }]
}
);
I made a function that get the JSON and try to save it like:
var QuestionSchema = require('./schemas/question');
var AnswerSchema = require('./schemas/answer');
CreateNewQuestion: function (message) {
var information = {
questionId: message.questionId,
subject: message.subject,
subsubject: message.subsubject,
}
//Save Question
var record = new QuestionSchema(information);
record.save(function (err) {});
}
How can I create the Answers object and populate them into the question?
I tried couple of things but keep getting error,
What is the proper way?
I tried to read in "mongoosejs.com/docs" but the site is down :(
I needed to change the model to:
module.exports = mongoose.model('Question' ,
{
subject: String,
subsubject: String,
questionText: String,
answerTimeAvg: Number,
fastestAnswer: Number,
answers: [{ type : mongoose.Schema.Types.ObjectId, ref: 'Answer' }]
} );
And save the answers first, and than use the IDs:
CreateNewQuestion: function (message) {
////////////////////////
// Saving the answers //
////////////////////////
var answers = message.answers;
var answers_ids = [];
for(var i in answers) {
var answer = new AnswerSchema(answers[i]);
answer.save();
answers_ids.push(answer._id);
}
/////////////////////////
// Saving the question //
/////////////////////////
var information = {
subject: message.subject,
subsubject: message.subsubject,
questionText: message.questionText,
answerTimeAvg: 0,
fastestAnswer: 0,
answers: answers_ids
}
var record = new QuestionSchema(information);
record.save(function (err) {
if (err) {
console.log("Bad = " + err);
var result = "bad";
message.sendReplay({result: result});
}
else {
var result = "AllGood";
message.sendReplay({result: result});
}
});
},
Related
A was using DataTables plugin, and when displaying my columns I needed to put the first letter to LowerCase for it to recognize the property/object, e.g:
// Object name is actually: EngineeringChange.Responsible
{
title: "Responsible",
data: "engineeringChange.responsible",
className: "columnName columnHeader",
},
I just assumed the first letter would always be capitalized to LowerCase. I tried creating a new property inside EngineeringChange named ECRNumber, so I tried:
{
title: "ECR Number",
data: "engineeringChange.eCRNumber",
className: "columnName columnHeader",
},
Isn't recognized as a parameter... After a bit of searching I find out the Json response I get on AJAX it's called ecrNumber. So now I'm actually lost on which are the rules that are automatically applied to the Json Response. How does it turn ecr to LowerCase and Number to UpperCase (the N)??
Edit
Sry, can´t think of any easy way to exactly reproduce my problem on a demo
TableDesign/Creation
table = $('#tblEntries2').DataTable({
order: [[0, 'desc']],
deferRender: true,
ajax: {
url: '#Url.Action("GetEntries", "AlteracaoEngenharia")',
method: 'GET',
dataSrc: '',
beforeSend: function () {
onBegin();
$content.hide();
$loader.show();
},
complete: function (jsonResponse) {
console.log(jsonResponse);
onComplete();
$loader.hide();
$content.fadeIn();
$('#ExcelExport').show();
table.column(5).visible(false);
table.column(6).visible(false);
table.column(7).visible(false);
table.column(9).visible(false);
table.column(10).visible(false);
table.column(11).visible(false);
}
},
dom: "<'row'<'col-2'l><'col-7 text-center'B><'col-3'f>>" +
"<'row'<'col-12'tr>>" +
"<'row'<'col-5'i><'col-7'p>>",
lengthMenu: [
[10, 25, 50, 100, -1],
['10', '25', '50', '100', 'Todos'],
],
columns: [
{
title: "Id (yr-id)",
data: "creationYear",
className: "columnNumber columnHeader",
},
{
title: "ECR Number",
data: "engineeringChange.ecrNumber",
className: "columnNumber columnHeader",
},
{
title: "Criador Alteração de Engenharia",
data: "engineeringChange.responsible",
className: "columnName columnHeader",
},
...
Handler
public IActionResult GetEntries()
{
GetDataEntries();
int count = 0;
int currentYear = 0;
foreach (var entry in EntriesList)
{
EngineeringChangesListViewModel h = new EngineeringChangesListViewModel
{
EngineeringChange = entry
};
if (currentYear != entry.DataCriacao.Year)
{
count = 1;
currentYear = entry.DataCriacao.Year;
}
else
{
count++;
}
h.DeadLine = entry.FinishedGood.Week + " - " + entry.DataCriacao.Year.ToString();
if (entry.OldPart == null)
{
h.EngineeringChange.OldPart = new Part();
}
if (entry.NewPart == null)
{
h.EngineeringChange.NewPart = new Part();
}
if (entry.FinishedGood == null)
{
h.EngineeringChange.FinishedGood = new FinishedGood();
}
if (entry.OldPart != null && entry.OldPart.CDP.HasValue)
h.OldPartValue = entry.OldPart.CDP * entry.OldPart.Stock;
if (entry.NewPart != null && entry.NewPart.CDP.HasValue)
h.NewPartValue = entry.NewPart.CDP * entry.NewPart.Stock;
h.EngineeringChange.ECRNumber = entry.ECRNumber;
//toString("D4") padds the number to always be 4 digits
h.CreationYear = entry.DataCriacao.Year.ToString() + "_" + count.ToString("D4");
h.IdYear = count;
EntriesListaViewModel.Add(h);
}
var errorsJson = JsonConvert.SerializeObject(EntriesListaViewModel);
Console.WriteLine(errorsJson);
return new JsonResult(EntriesListaViewModel);
}
HANDLER OUTPUT
[{"CreationYear":"2021_0001","IdYear":1,"OldPartValue":null,"NewPartValue":2061.09155,"DeadLine":"15 - 2021","EngineeringChange":{"Id":8,"DataCriacao":"2021-03-11T16:15:24.6630956","Responsible":"José António","ECRNumber":"X1232","State":"Aberto","Comment":"Teste","UserId":1,"User":null,"Component":null,"FinishedGood":{"Id":31,"Week":15,"EngineeringChangeId":8},"OldPart":{"Id":5,"Reference":"FS12848AC","Stock":null,"CDP":1.43584776,"LastExpired":null},"NewPart":{"Id":6,"Reference":"FS12848AD","Stock":1650,"CDP":1.24914646,"LastExpired":"2021-03-11T00:00:00"},"Transformation":{"Id":188,"Possible":true,"Cost":1090.0,"WillBeTransformed":true,"TransformationDate":"2021-03-13T08:48:00","Responsible":"Miguel","EngineeringChangeId":8}}},]
PAGE/AJAX OUTPUT outputs are created by console.log() and Console.WriteLine() displayed above.
ECRNumber gets named to ecrNumber...
I have made Custom Fields in my Users in Google Suite.
Category: Foresatt
Among them:
Name: 'foresatt epost', type:email, number: multiple values
I would like to list these values using Google Script. I used this:
https://developers.google.com/admin-sdk/directory/v1/quickstart/apps-script
To write this code:
function listUsers() {
var optionalArgs = {
customer: 'my_customer',
maxResults: 10,
orderBy: 'email',
projection: 'custom',
customFieldMask:'Foresatt'
};
var response = AdminDirectory.Users.list(optionalArgs);
var users = response.users;
if (users && users.length > 0) {
Logger.log('Users:');
for (i = 0; i < users.length; i++) {
var user = users[i];
var foresatt = user.customSchemas;
Logger.log('%s (%s)', user.primaryEmail, user.name.fullName, foresatt);
}
} else {
Logger.log('No users found.');
}
}
That works, but I would like to get only the values. What I get now:
{Foresatt={
foresatt_mob=[{value=X#X#X#X#, type=work}, {type=work, value=X#X#X#X#}, {type=work, value=X#X#X#X#}],
foresatt_epost=[{value=xx#xx.no, type=work}, {type=work, value=xy#xx.no}, {value=yy#xx.no, type=work}],
foresatt_navn=[{type=work, value=Xx}, {value=Xy, type=work}, {type=work, value=Yy}]
}
}
What I would like to get: xx#xx.no, xy#xx.no, yy#xx.no
I have tried several things, but I'm afraid I'm not experienced enough.
var epost = foresatt.foresatt_epost;
Results in: TypeError: Cannot read property 'foresatt_epost'
var epost = foresatt('foresatt_epost');
Results in: TypeError: foresatt is not a function
Please advise me, how do I get only the values fram the field 'foresatt epost'?
I believe your goal as follows.
You want to retrieve the values of xx#xx.no, xy#xx.no, yy#xx.no from the following object:
const object = {
Foresatt: {
foresatt_mob: [
{ value: "X#X#X#X#",type: "work"},
{ value: "X#X#X#X#",type: "work"},
{ value: "X#X#X#X#",type: "work"},
],
foresatt_epost: [
{ value: "xx#xx.no", type: "work"},
{ value: "xy#xx.no", type: "work"},
{ value: "yy#xx.no", type: "work"},
],
foresatt_navn: [
{ type: "work", value: "Xx"},
{ type: "work", value: "Xy"},
{ type: "work", value: "Yy"},
]
}
}
In this case, the values can be retrieved from the object.Foresatt.foresatt_epost array.
Sample script:
const object = {}; //Your object
const res = object.Foresatt.foresatt_epost.map(e => e.value);
console.log(res) // Outputs: [ 'xx#xx.no', 'xy#xx.no', 'yy#xx.no' ]
If user.customSchemas is the above object, the script is as follows.
var foresatt = user.customSchemas;
const res = foresatt.Foresatt.foresatt_epost.map(e => e.value);
console.log(res)
If you want to retrieve the value as a comma separated string, you can use res.join(",").
References:
map()
Note:
If there is no guarantee your property will exist in your object, you can do (object.property||[]).map(...) instead of object.property.map(...) to avoid the error Uncaught TypeError: Cannot read property 'forEach' of undefined.
I am trying to produce some messages to a single topic having 2 partitions. All the messages are going to partition number 2 only.
I would expect that a producer stream would distribute the messages across all partitions.
const kafka = require('kafka-node')
const { Transform } = require('stream');
const _ = require('lodash');
const client = new kafka.KafkaClient({ kafkaHost: 'localhost:9092' })
, streamproducer = new kafka.ProducerStream({kafkaClient: client});
const stdinTransform = new Transform({
objectMode: true,
decodeStrings: true,
transform (text, encoding, callback) {
let num = parseInt(text);
let message = { num: num, method: 'two' }
console.log('pushing message')
callback(null, {
topic: 'topic356',
messages: JSON.stringify(message)
});
}
});
stdinTransform.pipe(streamproducer);
function send() {
var message = new Date().toString();
stdinTransform.write([{ messages: [message] }]);
}
setInterval(send, 100);
ConsumerGroup:
var consumerOptions = {
kafkaHost: '127.0.0.1:9092',
groupId: 'ExampleTestGroup',
sessionTimeout: 15000,
protocol: ['roundrobin'],
fromOffset: 'latest' // equivalent of auto.offset.reset valid values are 'none', 'latest', 'earliest'
};
var topics = 'topic356';
var consumerGroup = new ConsumerGroup(Object.assign({ id: 'consumer1' }, consumerOptions), topics);
consumerGroup.on('data', onMessage);
var consumerGroup2 = new ConsumerGroup(Object.assign({ id: 'consumer2' }, consumerOptions), topics);
consumerGroup2.on('data', onMessage);
consumerGroup2.on('connect', function () {
setTimeout(function () {
consumerGroup2.close(true, function (error) {
console.log('consumer2 closed', error);
});
}, 25000);
});
function onMessage (message) {
console.log(
` partition: ${message.partition} `
);
}
Do you produce messages with a key? In Kafka, messages with the same key are published to the same partition.
use partitionerType in options, the default is 0,
Partitioner type (default = 0, random = 1, cyclic = 2, keyed = 3, custom = 4), default 0
new kafka.Producer(new kafka.KafkaClient({ kafkaHost: 'localhost:9092' }),{
partitionerType:1
});
https://github.com/SOHU-Co/kafka-node/issues/1094
Schema for my MongoDB model:
var resultsSchema = new mongoose.Schema({
start_date: String,
end_date: String,
matches:[{
id:Number,
match_date:String,
status:String,
timer:Number,
time:String,
hometeam_id:Number,
hometeam_name:String,
hometeam_score:Number,
awayteam_id:Number,
awayteam_name:String,
awayteam_score:Number,
ht_score:String,
ft_score:String,
et_score:String,
match_events:[{
id:Number,
type:String,
minute:Number,
team:String,
player_name:String,
player_id:Number,
result:String
}]
}]
});
Example of JSON data coming from the server:
"matches":
[
{
"match_id":"1234"
"match_date":"Aug 30"
...
...
"match_events":
[
{
"event_id":"234",
"event_minute":"38",
...,
...
},
{
"event_id":"2334",
"event_minute":"40",
...,
...
}
],
{
"match_id":"454222"
"match_date":"Aug 3"
...
...
"match_events":
[
{
"event_id":"234",
"event_minute":"38",
...,
...
},
....
My current implementation works for parsing just the matches (i.e the first array). But I can't seem to access the inner array properly.
async.waterfall([
function(callback) {
request.get('http://football-api.com/api/?Action=fixtures&APIKey=' + apiKey + '&comp_id=' + compId +
'&&from_date=' + lastWeek_string + '&&to_date=' + today_string, function(error, response, body) {
if (error) return next(error);
var parsedJSON = JSON.parse(body);
var matches = parsedJSON.matches;
var events = parsedJSON.matches.match_events;
var results = new Results({
start_date: lastWeek_string,
end_date: today_string,
matches:[]
});
_.each(matches, function(match) {
results.matches.push({
id: match.match_id,
match_date: match.match_formatted_date,
status:match.match_status,
timer:match.match_timer,
hometeam_id:match.match_localteam_id,
hometeam_name:match.match_localteam_name,
hometeam_score:match.match_localteam_score,
awayteam_id:match.match_visitorteam_id,
awayteam_name:match.match_visitorteam_name,
awayteam_score:match.match_visitorteam_score,
ht_score:match.match_ht_score,
ft_score:match.match_ft_score,
et_score:match.match_et_score,
match_events:[]
});
});
_.each(events, function(event) {
results.matches.match_events.push({
id:event.event_id,
type:event.event_type,
minute:event.event_minute,
team:event.event_team,
player_name:event.event_player,
player_id:event.event_player_id,
result:event.event_result
});
});
I understand that the second _.each loop should be iterating for every match, since very match has it's own events subarray. I'm just not sure how to structure this and have been struggling with it for a while.
I tried nesting that loop inside the _.each(matches, function(match) { loop but that didn't work.
Thank you.
Edit: How could I get this to work?
var results = new Results({
start_date: lastWeek_string,
end_date: today_string,
matches:[
match_events: []
]
});
Because then as #zangw says I could construct the match_events array first, append it to matches, and so on.
I am trying to output just the hometeam name's to the page so that I can try to understand how to work with my code better. It is only printing one team to the page, and it is printing all the details of that team to the page, whereas I only want it to print one part.
This is my code, I want it to print the name's of each hometeam to the page
app.get('/home', function(req, res) {
Match.findOne({}).populate('hometeam.name').exec(function(err, teams){
util.log(teams);
res.send(teams);
});
});
But when I load the page all I get is the first piece of data from this list of Matches
[
{
"hometeam": "5106e7ef9afe3a430e000007",
"_id": "5113b7ca71ec596125000005",
"__v": 0,
"key": 1360246730427
},
{
"hometeam": "5113c13e0eea687b28000001",
"_id": "5113e951354fe70330000001",
"__v": 0,
"key": 1360259409361
},
{
"hometeam": "5113c13e0eea687b28000001",
"_id": "5113e999354fe70330000002",
"__v": 0,
"key": 1360259481412
}
]
Also, if I try to put util.log(teams.hometeam.name) I get the following:
TypeError: Cannot call method 'toString' of undefined
But I would want it to be able to print the name which belongs to hometeam here. As hometeam is just the objectId of a Team in my database, am I missing something with the DBreferencing here?
Update:
Team Schema
var Team = new Schema({
'key' : {
unique : true,
type : Number,
default: getId
},
'name' : { type : String,
validate : [validatePresenceOf, 'Team name is required'],
index : { unique : true }
}
});
module.exports.Schema = Team;
module.exports.Model = mongoose.model('Team', Team);
Match Schema
var Team = require('../schemas/Team').Schema;
var Match = new Schema({
'key' : {
unique: true,
type: Number,
default: getId
},
'hometeam' : { type: Schema.ObjectId, ref: 'Team' },
'awayteam' : { type: Schema.ObjectId, ref: 'Team' }
});
module.exports = mongoose.model('Match', Match);
Populate takes the property name of the property you are trying to retrieve. This means that you should use 'hometeam' instead of 'hometeam.name'. However, you want to retrieve the name of the team so you could filter for that. The call would then become..
Match.findOne({}).populate('hometeam', {name: 1}).exec(function(err, teams)
Now you have a property called 'hometeam' with in that the name. Have fun :)
EDIT
Showing how to have a single mongoose instance in more files to have correct registration of schemas.
app.js
var mongoose = require('mongoose');
var Team = require('./schemas/team-schema')(mongoose);
var Match = require('./schemas/match-schema')(mongoose);
// You can only require them like this ONCE, afterwards FETCH them.
var Team = mongoose.model('Team'); // LIKE THIS
schemas/match-schema.js
module.exports = function(mongoose) {
var Match = new mongoose.Schema({
'key' : {
unique: true,
type: Number,
default: getId
},
'hometeam' : { type: mongoose.Schema.ObjectId, ref: 'Team' },
'awayteam' : { type: mongoose.Schema.ObjectId, ref: 'Team' }
});
return mongoose.model('Match', Match);
};
schemas/team-schema.js
module.exports = function(mongoose) {
var Team = new mongoose.Schema({
'key' : {
unique : true,
type : Number,
default: getId
},
'name' : { type : String,
validate : [validatePresenceOf, 'Team name is required'],
index : { unique : true }
}
});
return mongoose.model('Team', Team);
};