How do I get json data with retrhinkdb - node.js

(I'm not good eng.)
I use a group to include dates. I want to get the information out in a row. What do i need to do
.group(r.row('time_create').dayOfWeek())
json export
[
{
group: 1,
reduction: [
{
detail: "no",
id: "37751c10-97ea-4a3a-b2c9-3e8b39383b79",
order_id: "15",
status: "Not_Delivery",
time_create: "2018-09-23T15:25:13.141Z"
}
]
}
]
i want change data json to
{
"date":
{
"Sun": [
{
detail: "no",
order_id: "15",
status: "Not_Delivery",
time_create: "2018-09-28 15:25:13"
}
]
}
}
Do i have to give the information out as i want.

Looks like you tried but didn't manage to transform the data from your previous question. ;)
Here is a proposition, this is not the only way of doing it.
First, it seems you want to remove the id field. You may do that in your ReQL using without:
.group(r.row('time_create').dayOfWeek()).without('id')
(You may apply without('id') before group, it should work the same, see this for more details.)
Then, to transform the result array (let's call it queryResult) into an object (let's call it output):
// prepare the skeleton of the output
let output = {
date: {}
};
// walk the result, filling the output in the process
queryResult.forEach((groupData) => {
let key = groupData.group;
if (!output[key]) {
output[key] = [];
}
output.date[key].push(...groupData.reduction);
})
Now you almost have your desired structure in output, the only thing is that day keys are still numbers and not a short day name. In my opinion, this should be handled by the front-end, since you may want to have different languages implemented for your front-end. But anyway, the idea is always the same: having a translation table that maps Rethink's day numbers with human-readable day names:
const translationTable = {
1: 'Mon',
2: 'Tue',
// ...
7: 'Sun'
};
Now if you do that in your front-end, you just replace the data's keys on the fly, when displaying is needed (or retrieve the key from the day name, depending on how you display stuff). Otherwise, if you go for a back-end implementation (which, again, is clearly not the best solution), you can change one line in the code above (assuming you declared translationTable already):
let key = groupData.group;
// becomes
let key = translationTable[groupData.group];
Feel free to ask in comments if there's something you don't understand!

Related

Array of Structs returning unusual data in Solidity

I am creating one Voting Smart Contract people can organize one election and voters can vote for their candidate. I have created one function which will return the statistics of ongoing or past elections
///#dev making statistics for all ballot/election
///#return results with all the information of all
function getStatisticsOfAllVote()
public
view
returns (SingleElectionStatistics[] memory )
{
SingleElectionStatistics[] memory results = new SingleElectionStatistics[](BallotArray.length);
for (uint256 i = 0; i < BallotArray.length; i++) {
SingleElectionStatistics memory temp = SingleElectionStatistics(
BallotArray[i]._getName(), //CEO election
BallotArray[i]._getDescription(),//Employees will choose their CEO
BallotArray[i]._getTotalVoteCounted(),//BigNumber { value: "1" }
BallotArray[i]._isVotingEnded(),//true
BallotArray[i]._getWinningProposalName()//John
);
results[i] = temp;
}
return results;
}
Sample returns are added as comments after the function call.
I suppose to get one array of objects. Buts it gave me data unusual format with extra data. Here are the returns data:
[
[
'CEO election',
'Employees will choose their CEO',
BigNumber { value: "1" },
true,
'John',
name: 'CEO election',
description: 'Employees will choose their CEO',
voteCounted: BigNumber { value: "1" },
voteEnded: true,
winningProposalName: 'John'
]
]
Which should return only
[
{
name: 'CEO election',
description: 'Employees will choose their CEO',
voteCounted: BigNumber { value: "1" },
voteEnded: true,
winningProposalName: 'John'
}
]
I may need help from the community. Thanks in advance
I tried with unit tests and also by changing the approaches but it doesn't help at all.
The raw data returned from a node (using eth_call RPC method) is an ABI-encoded byte array, containing each item just once.
The duplication that you see is caused by an offchain framework. Based on other context, I'm assuming that you're using ethers.js.
Their docs page says:
A Result is an array, so each value can be accessed as a positional argument.
Additionally, if values are named, the identical object as its positional value can be accessed by its name.
In your case, the call returns an array of Result types. Since the Solidity return variables are named (your ethers.js instance knows this from the ABI JSON generated during Solidity compilation), each Result type contains both number-indexed and named items.

Increment a field conditioned by a WHERE

I can't seem to figure out how to do this in Sequelize. I have an instance from findOne, and I want to increment one of its fields using an expression, and only under certain conditions. Something such as:
UPDATE Account SET balance = balance - 10 WHERE balance >= 10;
I want the db to calculate the expression, as this isn't happening in a transaction. So I can't do a SET balance = 32. (I could do SET balance = 32 WHERE balance = 42, but that's not as effective.) I don't want to put a CHECK in there, as there are other places where I do want to allow a negative balance.
(Our Sequelize colleague has left, and I can't figure out how to do this).
I see the instance.increment and decrement, but it doesn't look like they take a where object.
I don't see how to express the setting of balance = balance - 10, nor of expressing the expression in the where object.
You are probably looking for Model.decrement instead of instance.decrement. instance.decrement is for updating the specific record so where doesn't make sense.
Model.decrement: https://sequelize.org/master/class/lib/model.js~Model.html#static-method-decrement
The example in the link shows similar scenario as yours.
============================================
Update:
This translates to your example.
const Op = require('sequelize').Op;
Account.decrement('balance', {
by: 10,
where: {
balance: {
[Op.gte]: 10
}
}
});
Based on #Emma comments, here's what I have working. amountToAdd is just that; cash_balance is the field I'm incrementing. The check on cash_balance ensures that if I'm decrementing (that is amount_to_add is < 0), the balance doesn't go below 0. I need to muck around with that some.
const options = {
where: {
user_id: userId,
cash_balance: {
[ Op.gte ]: amountToAdd,
},
},
by: amountToAdd
};
const incrResults = await models.User.increment( 'cash_balance', options );

How to return an entire array (NO FILTER!!!!!), from mongodb using node.js

heres my mongodb group document. As you can see i have an _id, which i use to find the group itself, an owner, an array of admins and an array of members.
{
"_id": {
"$oid": "60c7246f61a6cc7527f815d2"
},
"groupName": "soogroo1",
"creationDate": "11/06/2020",
"premiumStatus": true,
"phone": "08741536329995757575757575757575577575757575",
"profilePic": "post-5f2a01e2-efe3-4fa0-8302-76bfd2d70b4b-1622806860268",
"owner": ["9b8bcd57-06eb-471c-8910-c5b944d02431"],
"admin": ["f2171431-627e-47a3-a65f-4abf48d361b6", "5e3df015-a1ed-4a63-a16e-83458d0e7da3", "f85baa4a-1015-4a5e-b1ed-b79001a9f277"],
"member": ["6b1233b2-098e-480b-9462-c010c8b8de06", "0bcbb92d-6276-4118-8576-9d5f5c4ed43b"]
}
essentially i have searched the entirety of the world wide web looking for one of possibly the simplest most fundamental thing i can think of, how on gods green earth do you query an array of strings, and return the entire array. All i want to do is pass in a group id, specify that i want the entire member field returned, and then ill be able to map the members to a list on the front-end like you would with following/followers on instagram for example.
Everywhere i look all i can find is people who use arrays of objects and people who filter arrays and all that bs, i just want the entire array string for string returned. Please help i'm pulling my hair out lol.
BTW im using nodeJS with express and reactJS on the front-end (not that that's relevant)
vvvvv RELEVANT CODE vvvvv
folder name : routes
file name : groups.js
app.get("/groups/:groupId/members", (req, res)=>{
groups.getGroupsMembers(req.params.groupId).then(data=>{
res.send(data)
})
})
folder name : main
file name : groups.js
exports.getGroupsMembers = (groupId) => {
return myMongo.getGroupsMemberList("groups", groupId);
};
folder name : main
file name : mongo.js
vvvvvv (the part that is broken) vvvvvv
exports.getGroupsMemberList = (collection, groupId) => {
return db.collection(collection).findOne(
{ _id: ObjectID(groupId)},
).members
}
I currently have no way to test your code, but I guess your problem is because you are extending query with .members, not actually getting members attribute from the return value of query.
exports.getGroupsMemberList = async (collection, groupId) => {
return await (db.collection(collection).findOne(
{ _id: ObjectID(groupId)},
)).members
}
I am not sure if mongo driver accepts async/await, so you might need to do this through callbacks..?

Is there a way to create a dict object from user input() in python 3.7.1?

The purpose of this question is I want to write some request through pymongo.
For one criterion per field, this is not a difficulty to use input.
find_mongo = {}
key = input("enter a field :")
value = input("enter a criterion :")
find_mongo[key] = value
db.collection.find(find_mongo)#it works without problem.
That's more problematic when I want more complicated criteria.
For instance if I want the value to be in a range:
{"field":{"$lte":1,"$gte":0.5,"$exists:true"}}
Because for the user, who's my own-self, it would be very easier to write this in the shell:
enter a field : size
enter a criterion or criteria : {"$lte":1,"$gte":0.5,"$exists":true"}
the current issue is value returns a string object : '{"$lte":1,"$gte":0.5,"$exists":true"}'
and as far as I know, mongo is not able to find with a str expression but with a dict.
I want this too if I need to write even more complicated requests with "$or" nested in a "$and" expression:
{"$and":[
{"size":{"$lte":100}},
{ $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] }
]
}
and just have to write in an input the following example:
enter your request: {"$and":[
{"size":{"$lte":100}},
{ $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] }
]}
in order to be able to execute:
find_mongo = input("enter your request: ")
db.collection.find(find_mongo)
Sure it's easier from the mongoshell, but if I don't request from mongoshell is because I want to make transformation of the files of the request in python.
Besides I am not searching for a solution to obtain {"$lte":1,"$gte":0.5,"$exists":true"}. Honestly with some reflections, conditions and iterations, I think I am able to find a way. I am really searching if it is possible to enter and return an object, here a dict and not an str one, through the input() user. Just because it's easier for me if such a solution does exist.
Notes: Ubuntu 18.04, Python 3.7.1

How to chain groups of observables that previously were each one in a forkjoin() operation

I have an orders table in mysql, each order has a number of documents associated to it, whether they are quotes, invoices, etc. There is therefore a second table called "documents", which has a "document_id" primary key and a "order_id" foreign key; In a similar fashion, I have another case for the different checks that technicians do to every vehicle, then another table for vehicle pictures. I am creating a web service using Node and Express that needs to return a json that similar to this...
[
{
"order_id": 1003,
"customer_id": 8000,
"csi": 90,
"date_admitted": "2016-10-28T05:00:00.000Z",
"plates": "YZG-5125",
...
documents: {
"type": "invoice",
"number": "1234",
...
},
checks: {
"scanner": "good",
"battery": "average",
...
},
vehicle_pictures: {
"title": "a title...",
"path": "the file path"
...
}
},
{
...
},
...
]
As you can see, it is necessary to do three queries for each order, one for checks, another for documents and a third for pictures, then I need to add these sub results to the order for finally return the array in the response.
This would be a very easy task to do in the old world of synchronous programming, however due to the asynchronous nature of the query() method in the connection object of the mysql library, this threats to become a real hell.
In a situation where I would have to process a single order, using RxJS library on the server with a forkJoin() would suffice to process all three results at once, what I am not sure is how to "chain" every order (with a forkJoin for managing the 3 queries), so everything gets process and at the end I can call res.json(result) with everything neatly assembled.
Note: I want to solve this with RxJS instead of using a sync library package like node-mysql-libmysqlclient. The reason basically is that the "right" way to do this in an async language like Node JS is go async. Also I want to use RxJS and not async, q promises, or any other library since Observables seem to be the absolute winner in the async solutions contest and also want to be consistent in all the solutions I develop, so this question is mostly oriented for RxJS masters.
Also every single question I have found in so similar to this has the classical "purist" reply saying that if you are using Node you "should" use asynchronous and don't think in synchronous solutions. So this is a challenge for those that defend that position, since this (I think) is one of those cases where sync in Node makes sense, however I really want to learn how to do this with RxJS instead of thinking that this is impossible, which I am sure is not.
If I understood things correctly, you have some data that you want to to use to gather additional data from the database via async operations. You want to build a combined dataset consisting of the original data and the additional information that the subsequent queries have returned.
As you have mentioned, you can use forkJoin to wait for multiple operations to complete before proceeding. You have to do this for each item in the data sequence and then use switchMap to merge the result back into the original stream.
Have a look at the following example jsbin that demonstrate how this can be done:
const data = [
{ id: 1, init: 'a' },
{ id: 2, init: 'b' },
{ id: 3, init: 'c' }
]
function getA(id) {
return Rx.Observable.timer(1000)
.map(() => {
return { id, a: 'abc' }
})
.toPromise();
}
function getB(id) {
return Rx.Observable.timer(1500)
.map(() => {
return { id, b: 'def' }
})
.toPromise();
}
Rx.Observable.interval(5000)
.take(data.length)
.map(id => data[id])
.do(data => { console.log(`query id ${data.id}`)})
.switchMap((data) => {
return Rx.Observable.forkJoin(getA(data.id), getB(data.id), (a, b) => {
console.log(`got results for id ${data.id}`);
return Object.assign({}, data, a, b);
});
})
.subscribe(x => console.log(x));

Resources