The issue I am facing is that even though I am able to load the data in the database but the desired result is different from what is being returned.
The issue is that whenever I am running for loop the qn variable is inserted twice but need it only once.
Please if someone can help me resolve this issue.
userProject.js
router.post('/notification/check/upload/survey' , async (req,res) => {
//const taginsert = [];
const mcq = [];
//const newData = {};
//const o = {};
console.log(req.body);
for(var i=0; i<=req.body.questions.length-1;i++) {
// newData = {
// qn: req.body.questions[i].qn
// }
for(var j=0; j<=req.body.questions[i].options.length-1;j++){
const o =
{
qn: req.body.questions[i].qn,
//{
options: [{
option: req.body.questions[i].options[j].option,
totalValues: req.body.questions[i].options[j].totalValues
}]
}
// newData.options = o;
// newData.push(o);
mcq.push(o);
}
}
//mcq = newData;
const check = new userCampaignSurvey({
userId: req.body.userId,
status: 'Pending',
notification_type:req.body.notification_type,
questions: mcq
})
check.save((err,p) => {
if(err) {
res.status(500).send(err);
}
res.status(201).send(p);
})
})
model.js
userId:
{
type: Number,
required: true,
trim: true
},
notification_id:
{
type: Number,
},
notification_type:
{
type: Number,
required: true,
},
status:
{
type: String,
required: true
},
questions: [
{
qn: {
type: String,
required: true
},
options: [
{
option: {
type: String
},
totalViews: {
type:Number
}
}
]
},
],
created_at: {
type: Date,
required: true,
default: Date.now(),
},
});
result received
{
"userId": 1,
"notification_type": 1,
"status": "Pending",
"questions": [
{
"qn": "Which brand do you like better for buying shoes?",
"options": [
{
"option": "Adidas",
"_id": "639064c9ec215f2cd1b2b15d"
}
],
"_id": "639064c9ec215f2cd1b2b15c"
},
{
"qn": "Which brand do you like better for buying shoes?",
"options": [
{
"option": "Reebok",
"_id": "639064c9ec215f2cd1b2b15f"
}
],
"_id": "639064c9ec215f2cd1b2b15e"
}
],
"created_at": "2022-12-07T10:02:48.442Z",
"_id": "639064c9ec215f2cd1b2b15b",
"__v": 0
}
expected result
{
"userId": 1,
"status": "Pending",
"notification_type": 1,
"questions": [
{
"qn": "Which brand do you like better for buying shoes?",
"options": [
{
"option": "Adidas",
"totalViews": 20
},
{
"option": "Reebok",
"totalViews": 10
}
]
}
]
}
I looked at several of the suggested solutions but none seemed to rise to this confounding data formatting challenge.
I have a huge JSON file (over 100k rows) and massive duplicates of data all as top level objects. Here's an example:
[
{
"manufacturer":"Samsung",
"device":"Galaxy A32 5G",
"model":"SM-A326B",
"chipset":"Mediatek MT6853V/NZA",
"date":"2022-01-01",
"fw_id":"A326BXXS4AVA1",
"android":"R(Android 11)",
"known_passcode":false,
"afu":false,
"bfu":false,
"bruteforce":false
},
{
"manufacturer":"Samsung",
"device":"Galaxy A32 5G",
"model":"SM-A326U",
"chipset":"Mediatek MT6853V/NZA",
"date":"2021-03-01",
"fw_id":"A326USQU1AUD4",
"android":"R(Android 11)",
"known_passcode":true,
"afu":false,
"bfu":true,
"bruteforce":true
},
{
"manufacturer":"Samsung",
"device":"Galaxy A32 5G",
"model":"SM-A326U1",
"chipset":"Mediatek MT6853V/NZA",
"date":"2021-09-01",
"fw_id":"A326U1UEU5AUJ2",
"android":"R(Android 11)",
"known_passcode":true,
"afu":false,
"bfu":true,
"bruteforce":true
},
{
"manufacturer":"LGE",
"device":"LG K31",
"model":"LGL355DL",
"chipset":"Mediatek MT6762",
"date":"unknown",
"fw_id":"L355DL10l",
"android":"unknown",
"known_passcode":false,
"afu":false,
"bfu":false,
"bruteforce":false
}
]
This needs to be organized so that data points like manufacturer, device, model are not duplicated hundreds of times.
Btw, here's a JSFiddle to play with:
https://jsfiddle.net/xpancom/Lq7duahv/
Ideally, the JSON format would be the following:
[
{
"manufacturers": [
{
"manufacturer": "Samsung",
"devices": [
{
"device": "Galaxy A32 5G",
"models": [
{
"model": "SM-A326B",
"data": [
{
"chipset": "Mediatek MT6853V/NZA",
"date": "2022-01-01",
"fw_id": "A326BXXS4AVA1",
"android": "R(Android 11)",
"known_passcode": false,
"afu": false,
"bfu": false,
"bruteforce": false
},
{
"chipset": "Mediatek MT6853V/NZA",
"date": "2021-09-01",
"fw_id": "A326BXXU3AUH7",
"android": "R(Android 11)",
"known_passcode": true,
"afu": false,
"bfu": true,
"bruteforce": true
}
]
},
{
"model": "SM-A326U1",
"data": [
{
"chipset": "Mediatek MT6853V/NZA",
"date": "2021-09-01",
"fw_id": "A326U1UEU5AUJ2",
"android": "R(Android 11)",
"known_passcode": true,
"afu": false,
"bfu": true,
"bruteforce": true
}
]
}
]
}
]
},
{
"manufacturer": "LGE",
"devices": [
{
"device": "LG K31",
"models": [
{
"model": "SM-A326B",
"data": [
{
"chipset": "Mediatek MT6762",
"date": "unknown",
"fw_id": "L355DL10l",
"android": "unknown",
"known_passcode": false,
"afu": false,
"bfu": false,
"bruteforce": false
}
]
}
]
}
]
}
]
}
]
Working in React, here's what I've got so far in trying to massage this data:
const source = data;
const destination = [];
const classifiedTokens = []; // will be used to stored already classified tokens
const classifiedTokensModel = []; // will be used to stored already classified tokens for models
const getNextTokenArray = (source) => {
let unusedToken = null;
const nextTokenArray = source.filter(function (element) {
if (!unusedToken && !classifiedTokens.includes(element['device'])) {
unusedToken = element['device'];
classifiedTokens.push(unusedToken);
}
return unusedToken ? unusedToken === element['device'] : false;
});
return unusedToken ? nextTokenArray : null;
};
// Pass in arrays deconstructed from addToDestination to process third tier nested objects for models
const getNextTokenArrayModel = (tokenObject) => {
let tokenObjectDevice = tokenObject['device'];
let tokenObjectData = tokenObject['data'];
let unusedTokenModel = null;
const nextTokenArrayModel = tokenObjectData.filter(function (element) {
if (!unusedTokenModel && !classifiedTokensModel.includes(element['model'])) {
unusedTokenModel = element['model'];
classifiedTokensModel.push(unusedTokenModel);
}
return unusedTokenModel ? unusedTokenModel === element['model'] : false;
});
//return unusedTokenModel ? nextTokenArrayModel : null;
if (unusedTokenModel) {
if (nextTokenArrayModel.length === 0) return;
let res = {
device: tokenObjectDevice,
model: nextTokenArrayModel[0]['model'],
data: [],
};
nextTokenArrayModel.forEach((element) => {
res.data.push({
manufacturer: element.manufacturer,
chipset: element.chipset,
date: element.date,
fw_id: element.fw_id,
android: element.android,
knownPasscode: element.knownPasscode,
afu: element.afu,
bfu: element.bfu,
bruteforce: element.bruteforce,
});
});
destination.push(res);
} else {
return null;
}
};
const addToDestination = (tokenArray) => {
if (tokenArray.length === 0) return;
let res = {
device: tokenArray[0]['device'],
data: [],
};
tokenArray.forEach((element) => {
res.data.push({
manufacturer: element.manufacturer,
model: element.model,
chipset: element.chipset,
date: element.date,
fw_id: element.fw_id,
android: element.android,
knownPasscode: element.knownPasscode,
afu: element.afu,
bfu: element.bfu,
bruteforce: element.bruteforce,
});
});
getNextTokenArrayModel(res); // Call this to process and group nested model duplicates by device
//destination.push(res);
};
let nextTokenArray = getNextTokenArray(source);
while (nextTokenArray) {
addToDestination(nextTokenArray);
nextTokenArray = getNextTokenArray(source);
}
setTimeout(() => {
document.getElementById('root').innerHTML =
'<pre>' + JSON.stringify(destination, null, 2) + '</pre>';
}, 1000);
};
And here's the JSFiddle again:
https://jsfiddle.net/xpancom/Lq7duahv/
Who can smash this data formatting dilemma?
This answer is not React specific, but one approach would be to use array.reduce() to transform each level/node of the structure as shown in the code snippet below.
const source = [
{
manufacturer: 'Samsung',
device: 'Galaxy A32 5G',
model: 'SM-A326B',
chipset: 'Mediatek MT6853V/NZA',
date: '2022-01-01',
fw_id: 'A326BXXS4AVA1',
android: 'R(Android 11)',
known_passcode: false,
afu: false,
bfu: false,
bruteforce: false,
},
{
manufacturer: 'Samsung',
device: 'Galaxy A32 5G',
model: 'SM-A326B',
chipset: 'Mediatek MT6853V/NZA',
date: '2022-01-01',
fw_id: 'A326BXXS4AVA1',
android: 'R(Android 11)',
known_passcode: false,
afu: false,
bfu: false,
bruteforce: false,
},
{
manufacturer: 'Samsung',
device: 'Galaxy A32 5G',
model: 'SM-A326U',
chipset: 'Mediatek MT6853V/NZA',
date: '2021-03-01',
fw_id: 'A326USQU1AUD4',
android: 'R(Android 11)',
known_passcode: true,
afu: false,
bfu: true,
bruteforce: true,
},
{
manufacturer: 'Samsung',
device: 'Galaxy A32 5G',
model: 'SM-A326U1',
chipset: 'Mediatek MT6853V/NZA',
date: '2021-09-01',
fw_id: 'A326U1UEU5AUJ2',
android: 'R(Android 11)',
known_passcode: true,
afu: false,
bfu: true,
bruteforce: true,
},
{
manufacturer: 'LGE',
device: 'LG K31',
model: 'LGL355DL',
chipset: 'Mediatek MT6762',
date: 'unknown',
fw_id: 'L355DL10l',
android: 'unknown',
known_passcode: false,
afu: false,
bfu: false,
bruteforce: false,
},
];
function generateTree(data, key) {
return data.reduce((acc, val) => {
// Split the key name from the child data
const { [key.name]: keyName, ...childData } = val;
// Find a tree item in the structure being generated
const treeItem = acc.find((item) => item[key.name] === keyName);
if (treeItem) {
// If found, append child data
treeItem[key.child].push(childData);
} else {
// If not found, create new key and append child data
acc.push({ [key.name]: keyName, [key.child]: [childData] });
}
return acc;
}, []);
}
// Generate manufacturer/device structure
const manufacturers = generateTree(source, {
name: 'manufacturer', // Key name to use as grouping identifier
child: 'devices', // Key name for child data
});
// Generate device/model structure
manufacturers.forEach((manufacturer) => {
manufacturer.devices = generateTree(manufacturer.devices, {
name: 'device',
child: 'models',
});
// Generate model/data structure
manufacturer.devices.forEach((device) => {
device.models = generateTree(device.models, {
name: 'model',
child: 'data',
});
});
});
const destination = [{ manufacturers }];
console.log(destination);
BasicData {
userid:123123,
email:something#gmail.com
},
BusData {
Dropping: ....,
Boarding:......,
.....
......
},
Traveller1 {
name:....,
seatno0.....,
age:....,
},
Traveller2 {
name:....,
seatno0.....,
age:....,
},
Traveller3 {
name:....,
seatno0.....,
age:....,
},
Traveller4 {
name:....,
seatno0.....,
age:....,
}
In BookedBusdata there is table contains BasicData BusData and TravellerData. I want to access the the Data only consist of Travellers, But it may Traveller may be 2, 4 , 10 any number The Documents consist of only Map. But i want to all the data of Traveller which are in the form of Traveller1, Traveller2 whatever Traveller are there
var docRef = db.collection("BookedTicketData").doc(orderid);
docRef.get().then(function(doc) {
if (doc.exists) {
data = doc.data()
console.log(data.Traveller1.Age) // I am getting the data if i am accessing only one
} else {
// console.log("No such document!");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
This code i have performed
If you're happy to filter the data client side, it's a fairly straight forward task
const data = {
BasicData: {},
BusData: {},
Traveller1: {
name: 'Name1',
email: 'Email1'
},
Traveller2: {
name: 'Name2',
email: 'Email2'
},
Traveller3: {
name: 'Name2',
email: 'Email2'
},
}
// returns an array of travelers
console.log(Object.keys(data).reduce((acc, key) => {
if (key.includes('Traveller')) {
acc.push(data[key])
}
return acc;
}, []))
// returns an object of travelers
console.log(Object.keys(data).reduce((acc, key) => {
if (key.includes('Traveller')) {
acc[key] = data[key];
}
return acc;
}, {}))
In your case you can just use Object.keys(doc.data()).reduce...
I have my document like this
Sample document,
[
{
"_index": "xpertdox",
"_type": "disease",
"_id": "Ectopic Heartbeat",
"_score": 24.650267,
"_source": {
"category": "Condition",
"name": "Ectopic Heartbeat",
"dui": "D005117",
"url_name": "Extrasystole"
}
},
This is my sample document.
if (req.param('disease')) {
searchString = req.param('disease');
filterQuery = { Category:
['disease','Condition','speciality','pharm','medicine'] };
} else if (req.param('docorhosp')) {
searchString = req.param('docorhosp');
filterQuery = { Category: ['hospital', 'doctor'] };
} else if (req.param('speciality')) {
searchString = req.param('speciality');
filterQuery = { Category: ['speciality'] };
}
client.search({
index: 'xpertdox',
type: 'disease',
size: 20,
body: {
query: {
must: {
match: {
name: {
query: searchString,
fuzziness: 2,
operator: "or"
}
}
},
filter : {
terms : filterQuery
}
}
}
}).then(function (resp) {
var data = resp.hits.hits;
if (isFromSsr) {
data = helper.prepareSearchDataForSsr(data);
}
res.json(data);
});
I am matching my parameter with name,but here I want to filter records only whose category is either 'doctor' or 'hospital'.How can devolope my query so to get my requirement..
Try this:
client.search({
index: 'dox',
type: 'disease',
size: 20,
body: {
query: {
must: {
match: {
name: {
query: req.param('disease'),
fuzziness: 2,
operator: "or"
}
}
},
filter: {
terms: {
category: ['hospital', 'doctor']
}
}
}
}
})
[Previously titled "How to get 1 record from a list..."]
I am very new to GraphQL and trying to understand how to get 1 record from query.
This is the result of my current query:
{
"data": {
"todos": null
}
}
I am not sure what is wrong. I would like the result to be this:
{
"data": {
"todos": {
"id": 1,
"title": "wake up",
"completed": true
}
}
}
Here is my code that I've created as I try to learn GraphQL.
schema.js:
var graphql = require('graphql');
var TODOs = [
{
"id": 1,
"title": "wake up",
"completed": true
},
{
"id": 2,
"title": "Eat Breakfast",
"completed": true
},
{
"id": 3,
"title": "Go to school",
"completed": false
}
];
var TodoType = new graphql.GraphQLObjectType({
name: 'todo',
fields: function () {
return {
id: {
type: graphql.GraphQLID
},
title: {
type: graphql.GraphQLString
},
completed: {
type: graphql.GraphQLBoolean
}
};
}
});
var queryType = new graphql.GraphQLObjectType({
name: 'Query',
fields: function () {
return {
todos: {
type: new graphql.GraphQLList(TodoType),
args: {
id: { type: graphql.GraphQLID }
},
resolve: function (source, args, root, ast) {
if (args.id) {
return TODOs.filter(function(item) {
return item.id === args.id;
})[0];
}
return TODOs;
}
}
}
}
});
module.exports = new graphql.GraphQLSchema({
query: queryType
});
index.js:
var graphql = require ('graphql').graphql;
var express = require('express');
var graphQLHTTP = require('express-graphql');
var Schema = require('./schema');
var query = 'query { todos(id: 1) { id, title, completed } }';
graphql(Schema, query).then( function(result) {
console.log(JSON.stringify(result,null," "));
});
var app = express()
.use('/', graphQLHTTP({ schema: Schema, pretty: true }))
.listen(8080, function (err) {
console.log('GraphQL Server is now running on localhost:8080');
});
To run this code I just run node index from the root directory. How can I get one specific record returned by the records id?
You have the wrong type for the todos field of your queryType. It should be TodoType, not a list of TodoType. You're getting an error because GraphQL expects to see a list, but your resolver is just returning a single value.
By the way, I suggest passing the graphiql: true option to graphqlHTTP, which will let you use GraphiQL to explore your schema and make queries.