Monogo DB Update Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters - mongodb

So I am using my Express server to try update an array on my MongoDB.
My data looks like this:
{
"ID": "1",
"Name": "John",
"Image URL": "https://www.bnl.gov/today/body_pics/2017/06/stephanhruszkewycz-hr.jpg",
"Email": "",
"userSkillIds": ["1","2"]
},
{
"ID": "2",
"Name": "Sarah",
"Image URL": "https://www.venmond.com/demo/vendroid/img/avatar/big.jpg",
"Email": "",
"userSkillIds": ["3"]
},
I am trying to insert just a single String number in to the userSkillIds array using this code
router.put('/task/:id',function(req,res,next) {
var obj = req.body;
let skillId = obj.skillId;
if(obj == null || obj == {} ) {
res.status(400);
res.json({
"error": "Bad Data"
});
}else {
db.tasks.update(
{ _id: mongojs.ObjectID(req.params.id)},
{ $push: { userSkillIds: { 1: skillId } } }
)
res.json();
}
});
However I continuously get the error Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters.
Any help would be greatly appreciated!

May be your syntax is incorrect, use push operator as follows
db.tasks.update( { _id: 1 }, { $push: { userSkillIds: 89 } } )

Related

How to create in mongoose, if it exists, update it in mongoose

I have problem when I want create new model or if not exist, update it.
For example, I have data in a database:
{
"unix": 1668380400,
"type": "soup",
"order": 1,
"value": "Chicken"
},
{
"unix": 1668380400,
"type": "main",
"order": 0,
"value": "Gulash"
},
{
"unix": 1668553200,
"type": "soup",
"order": 0,
"value": "Asian"
}
}
I want to get to the point that when unix and type and order are the same - modify the value. But if the element with the same unix, order and type is not found in the database - add a completely new record to the db.
I thought this was how I would achieve the desired state. But a mistake.
router.post("/add", async (req, res) => {
const data = req.body;
await data.map((el) => {
const { unix, type, order, value } = el;
Menu.findOneAndUpdate(
{ unix, type, order },
{ unix, type, order, value },
{ new: true, upsert: true }
);
});
res.status(201).json({ status: true });
});
req.body:
[
{
"unix": 1668380400,
"type": "main",
"order": 2,
"value": "Sushi"
},
{
"unix": 1668553200,
"type": "soup",
"order": 0,
"value": "Thai"
}
]
Thanks for any help.
I think I found a solution. Everything works as it should, but wouldn't it be better to send the data with JSON.stringify() and then parse this data on the servers using JSON.parse()?
Another thing is the map method. Is it OK like this? Can't cause throttling?
router.post("/add", (req, res) => {
const data = req.body;
data.map(async (el) => {
const { unix, type, order, value } = el;
await Menu.findOneAndUpdate(
{ unix, type, order },
{ value },
{ upsert: true }
);
});
res.status(201).json({ status: true });
});

Search Key in Nested json in Dart/Flutter

I want to search the key "AylaHeartBeatFrequency" inside nested json. how to search and get its value ? in flutter/dart
{
"sAWSIoT": {
"CloudStatus": 1,
"PairingFlag": 0,
},
"sDebug": {
"LocalDebugMsg_d": "Model ID",
"AylaHeartBeatFrequency": 0
},
"Product": {
"Mode": 1,
"Model": "abc"
},
"data": {
"DeviceType": 300,
"Endpoint": 0,
"UniID": "0000000000000000"
}
}
You can do:
var map = /*put your json here. You can use json.decode() on the json if it's not yet formatted*/, value;
for(var item in map.values) {
if(item.containsKey('AylaHeartBeatFrequency') value = item['AylaHeartBeatFrequency']) ;
}

How to return the a formatted response from a mongo query/projection?

I'm trying to create an API to validate a promocode. I have minimal experience with mongo and the backend in general so I'm a bit confused in what is the best approach to do what I'm trying to accomplish.
I have this PromoCode form in the client. When a user types a promocode I would like for my backend to
verify if the code exists in one of the docs.
if it exists then return that code, the value for that code and the couponId
if the code doesn't exist then return an error.
My db is structured like this. The user will type one of those codes inside the codes: []
{
"_id": {
"$oid": "603f7a3b52e0233dd23bef79"
},
"couponId": "rate50",
"value": 50,
"codes": ["K3D01XJ50", "2PACYFN50", "COKRHEQ50"]
},
{
"_id": {
"$oid": "603f799d52e0233dd23bef78"
},
"couponId": "rate100",
"value": 100,
"codes": ["rdJ2ZMF100", "GKAAYLP100", "B9QZILN100"]
}
My route is structure like this:
router.post('/promoCode', (req, res, next) => {
const { promoCode } = req.body;
console.log('this is the req.body.promoCode on /promoCode', promoCode)
if (!promoCode) {
throw new Error('A promoCode needs to be passed')
}
promoCodesModel
.validatePromoCode(req.body.promoCode)
.then((response) => {
console.log('response inside /promoCode', response)
res.status(200).json({ data: response })
})
.catch((error) => {
res.status(400).json({ result: 'nok', error: error })
})
})
The validatePromoCode function is the following:
const validatePromoCode = async (code) => {
try {
let promoCode = await PromoCodesModel.find(
{"codes": code},
{_id: 0, codes: { $elemMatch: { $eq: code }} })
console.log('This is the promocode', promoCode)
return promoCode
} catch (err) {
throw new Error (err.stack)
}
}
All this seems to sort of work since I get the following response when the code is typed correctly
{
"data": [
{
"codes": [
"COKRHEQ50"
]
}
]
}
when typed incorrectly I get
{
"data": []
}
What I would like to get back is. (How can I accomplish this ?). Thanks
// when typed correctly
{
"data": { value: 50, couponId: "rate50", code: "COKRHEQ50" }
}
// when typed incorrectly
{
"error": "this is not valid code"
}
TL;DR: I would like to return a formatted query with specific values from a mongo query or an error object if that value does not exist on the document object.
Ok just figured it out
To be able to get the this responsed (what I wanted):
{
"data": [
{
"codes": [
"K3D01XJ50"
],
"couponId": "rate50",
"value": 50
}
]
}
I ended up having to do this on validatePromoCode
onst validatePromoCode = async (code) => {
try {
let promoCode = await PromoCodesModel.find(
{ codes: code },
{ _id: 0, codes: { $elemMatch: { $eq: code } }, couponId: 1, value: 1 },
)
return promoCode
} catch (err) {
throw new Error(err.stack)
}
}
But is there a better way on doing this ? Thanks

Error Unknown type "DateTime" on Apollo Payload of gql

I have a lot of problem, but this time my problem is GraphQL and its payload, my schema.gql and resolvers.js files looks like these:
# schema.gql
scalar GraphQLDateTime
scalar GraphQLDate
scalar GraphQLTime
type Query {
magicQuery(
idMagic: Int
magicDate: GraphQLDateTime
): DamnWow
}
type DamnWow {
_id: String
magicDateResult: GraphQLDateTime
}
# resolvers.js
const { GraphQLDate, GraphQLTime, GraphQLDateTime } = require('graphql-iso-date');
const resolvers = {
Query: {
magicQuery: async (root, { idMagic, magicDate }, context) => {
// It's never enter here
console.warn(idMagic, magicDate);
const result = { _id: 'wow1', magicDate: new Date() };
return result;
}
},
GraphQLDateTime: GraphQLDateTime,
GraphQLDate: GraphQLDate,
GraphQLTime: GraphQLTime
};
module.exports = resolvers;
When I try to use my payload with a query like that:
# query
query magicQuery($idMagic: Int, $magicDate: DateTime) {
magicQuery(idMagic: $idMagic, magicDate: $magicDate) {
_id
magicDateResult
}
}
# variables
# {
# "idMagic": 1,
# "magicDate": "2007-12-03T10:15:30Z"
# }
it's return me an error:
{
"error": {
"errors": [
{
"message": "Unknown type \"DateTime\".",
"locations": [
{
"line": 1,
"column": 45
}
],
"extensions": {
"code": "GRAPHQL_VALIDATION_FAILED",
"exception": {
"stacktrace": [
"GraphQLError: Unknown type \"DateTime\".",
" at Object.NamedType (/home/alex/workspace/team/node_modules/graphql/validation/rules/KnownTypeNamesRule.js:57:29)",
" at Object.enter (/home/alex/workspace/team/node_modules/graphql/language/visitor.js:323:29)",
" at Object.enter (/home/alex/workspace/team/node_modules/graphql/utilities/TypeInfo.js:370:25)",
" at visit (/home/alex/workspace/team/node_modules/graphql/language/visitor.js:243:26)",
" at Object.validate (/home/alex/workspace/team/node_modules/graphql/validation/validate.js:69:24)",
" at validate (/home/alex/workspace/team/node_modules/apollo-server-core/dist/requestPipeline.js:221:34)",
" at Object.<anonymous> (/home/alex/workspace/team/node_modules/apollo-server-core/dist/requestPipeline.js:118:42)",
" at Generator.next (<anonymous>)",
" at fulfilled (/home/alex/workspace/team/node_modules/apollo-server-core/dist/requestPipeline.js:5:58)"
]
}
}
}
]
}
}
If I use same parameter directy in my code it works fine.
Does someone know the cause of this error?
Your scalar type name in the schema is GraphQLDateTime but in the request you are using DateTime.
Try changing the request to:
query magicQuery($idMagic: Int, $magicDate: GraphQLDateTime) {
magicQuery(idMagic: $idMagic, magicDate: $magicDate) {
_id
magicDateResult
}
}

How to multiply NumberDecimal values in mongodb

I have the following structure:
{
"_id": "5d0118f0f57a282f89bc5f71",
"product": {
"_id": "5cfed37375a13067dd01ddb7",
"name": "My product",
"description": "My description",
"purchased_amount": 15,
"unit_price_mex": "45",
"unit_price_to_sell": "5",
"travel": "5cf58713d6f7f1657e2d8302",
"__v": 0,
"id": "5cfed37375a13067dd01ddb7"
},
"client": {
"_id": "5cf1778efffb651fad89d8b6",
"name": "Client name",
"description": "",
"__v": 0
},
"purchased_amount": 3,
"fch": "13/6/2019",
"__v": 0
},
{
"_id": "5d0151afda1a446008f1817b",
"product": {
"_id": "5cfed1995eaf2665c45efd82",
"name": "Camisa",
"description": "Camisas buenas",
"purchased_amount": 10,
"unit_price_mex": "100",
"unit_price_to_sell": "15",
"travel": "5cf56b04462a865264fabb9d",
"__v": 0,
"id": "5cfed1995eaf2665c45efd82"
},
"client": {
"_id": "5cf1778efffb651fad89d8b6",
"name": "Randy",
"description": "El que trabaja aqui",
"__v": 0
},
"purchased_amount": 34,
"fch": "12/6/2019",
"__v": 0
},
Where client and product are of type ObjectId. This is the Schema:
Client Model
var mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
var clientSchema = new mongoose.Schema({
name: String,
description: String
}).plugin(mongoosePaginate);
var Client = mongoose.model('Client', clientSchema);
module.exports = Client;
Product Model
var mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
var productSchema = new mongoose.Schema({
name: String,
description: String,
purchased_amount: Number,
unit_price_mex: mongoose.Schema.Types.Decimal128,
unit_price_to_sell: mongoose.Schema.Types.Decimal128,
travel: { type: mongoose.Schema.Types.ObjectId, ref: 'Travel' }
}).plugin(mongoosePaginate);
productSchema.set('toJSON', {
getters: true,
transform: (doc, ret) => {
if (ret.unit_price_mex) {
ret.unit_price_mex = ret.unit_price_mex.toString();
}
if ( ret.unit_price_to_sell ) {
ret.unit_price_to_sell = ret.unit_price_to_sell.toString();
}
}
})
var Product = mongoose.model('Product', productSchema);
module.exports = Product;
I need to get the multiplication sum of purchased_amount by product.unit_price_to_sell. My code is the following but always returns 0. Apparently, "$product.unit_price_to_sell" does not return the decimal value.
var aggregate = InvoiceModel.aggregate([
{ $match: { client: mongoose.Types.ObjectId( id ) } },
{ $group: { _id: null, total: { $sum: { $multiply: [ "$purchased_amount", "$product.unit_price_to_sell" ] } } } }
]);
InvoiceModel.aggregatePaginate(aggregate, {}, (error, aggs) => {
InvoiceModel.paginate({ client: id },{ page, limit, populate: 'client product' }, (err, value) => {
return res.status(200).send({
results: value.docs,
totalPages: value.totalPages,
totalDocs: value.totalDocs,
purchase_amount_total : aggs.docs[0].total
})
})
})
MongoDB cannot use string values in arithmetic expressions. You must either store the values using their numeric non-string representations, or you must use an aggregation operator like $toDecimal to convert the values to their numeric representations first.
Modifying your $group stage to something like the following should work:
{ $group: { _id: null, total: { $sum: { $multiply: [ "$purchased_amount", { $toDecimal: "$product.unit_price_to_sell" } ] } } }
Please note, however, that this will only work for MongoDB versions >= 4.0. If you're using an older version of MongoDB, you will either need to upgrade it to at least version 4.0 or begin converting your existing values from strings to numbers.