AWS IoT rules SQL query Select not returning expected values from shadow - sql

I am trying to create a rule that publishes the selected data from the things shadow.
My SQL query is
SELECT state FROM '$aws/things/+/shadow/update/accepted'
I would expect this to return both the desired and reported but it only return one object and not nested.
{
temp: 200,
io: false
}
instead of
{
desired: {
temp: 200,
io: true
},
reported: {
temp: 200,
io: false
}
}
so then I tried doing
SELECT state.desired, state.reported FROM '$aws/things/+/shadow/update/accepted'
and I only recieve the the object, basically which ever I put at the end of the SELECT statement after the ,
Anyone have any idea? I am trying to strip out all the metadata and timestamps.

Found the answer for whoever comes across this in the future. In the rule creation above where you enter your SQL Query, you need to change the SQL version to beta.

Related

FaunaDB: how to fetch a custom column

I'm just learning FaunaDB and FQL and having some trouble (mainly because I come from MySQL). I can successfully query a table (eg: users) and fetch a specific user. This user has a property users.expiry_date which is a faunadb Time() type.
What I would like to do is know if this date has expired by using the function LT(Now(), users.expiry_date), but I don't know how to create this query. Do I have to create an Index first?
So in short, just fetching one of the users documents gets me this:
{
id: 1,
username: 'test',
expiry_date: Time("2022-01-10T16:01:47.394Z")
}
But I would like to get this:
{
id: 1,
username: 'test',
expiry_date: Time("2022-01-10T16:01:47.394Z"),
has_expired: true,
}
I have this FQL query now (ignore oauthInfo):
Query(
Let(
{
oauthInfo: Select(['data'], Get(Ref(Collection('user_oauth_info'), refId))),
user: Select(['data'], Get(Select(['user_id'], Var('oauthInfo'))))
},
Merge({ oauthInfo: Var('oauthInfo') }, { user: Var('user') })
)
)
How would I do the equivalent of the mySQL query SELECT users.*, IF(users.expiry_date < NOW(), 1, 0) as is_expired FROM users in FQL?
Your use of Let and Merge show that you are thinking about FQL in a good way. These are functions that can go a long way to making your queries more organized and readable!
I will start with some notes, but they will be relevant to the final answer, so please stick with me.
The Query function
https://docs.fauna.com/fauna/current/api/fql/functions/query
First, you should not need to wrap anything in the Query function, here. Query is necessary for defining functions in FQL that will be run later, for example, in the User-Defined Function body. You will always see it as Query(Lambda(...)).
Fauna IDs
https://docs.fauna.com/fauna/current/learn/understanding/documents
Remember that Fauna assigns unique IDs for every Document for you. When I see fields named id, that is a bit of a red flag, so I want to highlight that. There are plenty of reasons that you might store some business-ID in a Document, but be sure that you need it.
Getting an ID
A Document in Fauna is shaped like:
{
ref: Ref(Collection("users"), "101"), // <-- "id" is 101
ts: 1641508095450000,
data: { /* ... */ }
}
In the JS driver you can use this id by using documentResult.ref.id (other drivers can do this in similar ways)
You can access the ID directly in FQL as well. You use the Select function.
Let(
{
user: Get(Select(['user_id'], Var('oauthInfo')))
id: Select(["ref", "id"], Var("user"))
},
Var("id")
)
More about the Select function.
https://docs.fauna.com/fauna/current/api/fql/functions/select
You are already using Select and that's the function you are looking for. It's what you use to grab any piece of an object or array.
Here's a contrived example that gets the zip code for the 3rd user in the Collection:
Let(
{
page: Paginate(Documents(Collection("user")),
},
Select(["data", 2, "data", "address", "zip"], Var("user"))
)
Bring it together
That said, your Let function is a great start. Let's break things down into smaller steps.
Let(
{
oauthInfo_ref: Ref(Collection('user_oauth_info'), refId)
oauthInfo_doc: Get(Var("oathInfoRef")),
// make sure that user_oath_info.user_id is a full Ref, not just a number
user_ref: Select(["data", "user_id"], Var("oauthInfo_doc"))
user_doc: Get(Var("user_ref")),
user_id: Select("id", Var("user_ref")),
// calculate expired
expiry_date: Select(["data", "expiry_date"], Var("user_doc")),
has_expired: LT(Now(), Var("expiry_date"))
},
// if the data does not overlap, Merge is not required.
// you can build plain objects in FQL
{
oauthInfo: Var("oauthInfo_doc"), // entire Document
user: Var("user_doc"), // entire Document
has_expired: Var("has_expired") // an extra field
}
)
Instead of returning the auth info and user as separate points if you do want to Merge them and/or add additional fields, then feel free to do that
// ...
Merge(
Select("data", Var("user_doc")), // just the data
{
user_id: Var("user_id"), // added field
has_expired: Var("has_expired") // added field
}
)
)

Multiple MySQL queries returning undefined when outputting value

I am running two database queries to retrieve data that I will outputting in a message embed. The queries are returning the proper rows when I just dump the entire result into the console. However, whenever I try to output the actual value for one of the rows, it displays as undefined in the message embed.
From what I've found based on examples, rows[0].somevalue should be outputting the correct results.
let mentionedUser = message.mentions.members.first();
let captainUser = client.users.find(user => user.id == `${mentionedUser.id}`);
con.query(`SELECT * FROM captains WHERE id = '${mentionedUser.id}';SELECT * FROM results WHERE captain = '${captainUser.username}'`, [2, 1], (err, rows) => {
if(err) throw err;
console.log(rows);
const infoEmbed = new Discord.RichEmbed()
.setColor("#1b56af")
.setAuthor('Captain Information', client.user.displayAvatarURL)
.setThumbnail('https://i.imgur.com/t3WuKqf.jpg')
.addField('Captain Name', `${mentionedUser}`, true)
.addField('Cap Space', `${rows[0].credits}`, true) // Returns undefined
message.channel.send(infoEmbed);
});
This is the console result
[ [ RowDataPacket {
id: '91580646270439424',
team_name: 'Resistance',
credits: 85,
roster_size: 2 } ],
[ RowDataPacket { id: 'Sniper0270', captain: 'BTW8892', credits: 10 },
RowDataPacket { id: 'Annex Chrispy', captain: 'BTW8892', credits: 5 } ] ]
In the code posted above, the expected output of rows[0].credits should output 85. No error codes are present, it just displayed as "undefined" in the message embed.
You are executing two queries inside a single query call. It looks like the mysql library returns an array of arrays in this scenario where the first value is the result of the first query and the second is the result of the second query. This is non standard. Normally you would either execute each query in its own query call or you would use a union to join the two queries into a single resultset.
this is not the practical way to send query request , as query is a single statement excluding the bulk update , you cannot execute two different query using a single con.query , it is not a proper way. execute them separately

How to make a Dynamic/Optional Filter(parameters) in mongo DB query at (Jasper Studio)

I'm creating a web aplication and it's working perfectly, but at the end user need to create a report from it's data.
On the report page I created some txt boxes where users will type for filtering. Those txt boxes could be empty and I need to return everything from the DB, or some parameter could be filled. Remenbering that I need to pass txt boxes content as params to JasperServer and they will be used in the Query.
A example of data input is:
txtName= empty (null),
txtCity= 'Belo Horizonte'
It should generate a report with all record of people how lives in Belo Horizonte no matter the name.
I made it in SQL and works perfect. After I tried to use the same logic on mongo but it doesn't work. I have tried with $lt, $gt, $lte, $gte, $exist, $ne and bunch other aggregation tool and I was not able to make it propertly.
SQL:
select * from myfirstreports
where ($P{city} is null or cidade =$P{city})
AND ($P{name} is null or nome =$P{name})
Mongo:
{
'collectionName' : 'myfirstreports',
'findFields' :
{
'nome': 1, 'numeros': 1, 'vulgo': 1, 'cidade': 1,
'usuResponsavelCadastro': 1, 'created_at': 1
},
findQuery :
{
$and: [
{$or:[{ $P{city}: {$eq: null}}, {'cidade': $P{city}}]},
{ $or:[{$P{name}: {'$eq': null}}, {'nome': $P{name}}]}
]
}
}
I used the following expression:
$P{city}.equals(null)? "{ }" : "{'cidade': '$P!{city}'}"//Need to create a non prompting parameter
$P{name}.equals(null)? "{ }": "{'nome': '$P!{name}'}"
$P!{...} parameters allows me to create a query as a string and pass to JasperSoft report.

Vue instance data not the same as network response, where is the bug?

Network response:
Vue instance:
Expected network response would be that the all_members would show all (in my case 12) club_members. If I query without using first/skip, it shows only 10 club_members (which is incorrect)
I currently have found a workaround with letting data.totalClubMembers.club_members override the data.club.all_members. Related discussion here: https://github.com/Akryum/vue-apollo/issues/196
(A part of) the query with arguments: $where: 1, $first: 10, $skip: 0.
query club($where: ClubWhereUniqueInput!, $first: Int, $skip: Int){
club: club(where: $where){
name
all_members: club_members {
id
}
club_members: club_members(first: $first, skip: $skip) {
id
category
club_reference_id
valid_from
valid_to
}
}
totalClubMembers: club(where: $where){
club_members {
id
}
}
}
Please advise:
if/where I made a mistake
if there is a more "optimal" solution.
Only root aliases seem to work for now (dec. 2018): https://github.com/prisma/graphql-yoga/issues/340
Refactor into 2 graphql queries will solve it.

Map/Reduce over sharded data with RavenDB

I'm having trouble getting a map reduce sample to work when the data is sharded across two nodes. I'm storing documents that relate to application errors being logged on two local ravenDB nodes, the error documents look like:
Example of document on node 1, there are 6 total
errors/1/6
{
"UniqueId": "c62c7e30-8ec7-45af-88e4-da023d796727",
"ApplicationName": "MyAppName"
}
Example of document on node 2, there are 7 total
errors/2/6 --Error stored on shard node 2
{
"UniqueId": "7e0b0f87-9d75-4e70-9fa0-d64a18bc88dc",
"ApplicationName": "MyAppName"
}
when I run this query:
public class ApplicationNames : AbstractIndexCreationTask<ErrorDocument, Application>
{
public ApplicationNames()
{
Map = errors => from error in errors
select new { error.ApplicationName, Count = 1 };
Reduce = results => from error in results
group error by new { error.ApplicationName, error.Count } into g
select new { g.Key.ApplicationName, Count = g.Sum(x=> x.Count) };
}
}
I'm getting back 2 results; one with a Count of 6, the second with a Count of 7. I was expecting that the two results from each shard would be combined into one result with a count of 13. Not sure if I'm doing something wrong or if that's not how its supposed to work. I followed the example at http://ravendb.net/documentation/docs-sharding to set up the sharding strategy.
Grant,
RavenDB currently doesn't handle reduce over multiple nodes.
You can do that yourself using:
session.Query<Application, ApplicationNames>()
.ToList()
.Select(new ApplicationNames().Reduce)
.ToList();