Cannot query on a date range, get back no results each time - node.js

I'm having a hard time understanding why I keep getting 0 results back from a query I am trying to perform. Basically I am trying to return only results within a date range. On a given table I have a createdAt which is a DateTime scalar. This basically gets automatically filled in from prisma (or graphql, not sure which ones sets this). So on any table I have the createdAt which is a DateTime string representing the DateTime when it was created.
Here is my schema for this given table:
type Audit {
id: ID! #unique
user: User!
code: AuditCode!
createdAt: DateTime!
updatedAt: DateTime!
message: String
}
I queried this table and got back some results, I'll share them here:
"getAuditLogsForUser": [
{
"id": "cjrgleyvtorqi0b67jnhod8ee",
"code": {
"action": "login"
},
"createdAt": "2019-01-28T17:14:30.047Z"
},
{
"id": "cjrgn99m9osjz0b67568u9415",
"code": {
"action": "adminLogin"
},
"createdAt": "2019-01-28T18:06:03.254Z"
},
{
"id": "cjrgnhoddosnv0b67kqefm0sb",
"code": {
"action": "adminLogin"
},
"createdAt": "2019-01-28T18:12:35.631Z"
},
{
"id": "cjrgnn6ufosqo0b67r2tlo1e2",
"code": {
"action": "login"
},
"createdAt": "2019-01-28T18:16:52.850Z"
},
{
"id": "cjrgq8wwdotwy0b67ydi6bg01",
"code": {
"action": "adminLogin"
},
"createdAt": "2019-01-28T19:29:45.616Z"
},
{
"id": "cjrgqaoreoty50b67ksd04s2h",
"code": {
"action": "adminLogin"
},
"createdAt": "2019-01-28T19:31:08.382Z"
}]
Here is my getAuditLogsForUser schema definition
getAuditLogsForUser(userId: String!, before: DateTime, after: DateTime): [Audit!]!
So to test I would want to get all the results in between the last and first.
2019-01-28T19:31:08.382Z is last
2019-01-28T17:14:30.047Z is first.
Here is my code that would inject into the query statement:
if (args.after && args.before) {
where['createdAt_lte'] = args.after;
where['createdAt_gte'] = args.before;
}
console.log(where)
return await context.db.query.audits({ where }, info);
In playground I execute this statement
getAuditLogsForUser(before: "2019-01-28T19:31:08.382Z" after: "2019-01-28T17:14:30.047Z") { id code { action } createdAt }
So I want anything that createdAt_lte (less than or equal) set to 2019-01-28T17:14:30.047Z and that createdAt_gte (greater than or equal) set to 2019-01-28T19:31:08.382Z
However I get literally no results back even though we KNOW there is results.
I tried to look up some documentation on DateTime scalar in the graphql website. I literally couldn't find anything on it, but I see it in my generated prisma schema. It's just defined as Scalar. With nothing else special about it. I don't think I'm defining it elsewhere either. I am using Graphql-yoga if that makes any difference.
(generated prisma file)
scalar DateTime
I'm wondering if it's truly even handling this as a true datetime? It must be though because it gets generated as a DateTime ISO string in UTC.
Just having a hard time grasping what my issue could possibly be at this moment, maybe I need to define it in some other way? Any help is appreciated

Sorry I misread your example in my first reply. This is what you tried in the playground correct?
getAuditLogsForUser(
before: "2019-01-28T19:31:08.382Z",
after: "2019-01-28T17:14:30.047Z"
){
id
code { action }
createdAt
}
This will not work since before and after do not refer to time, but are cursors used for pagination. They expect an id. Since id's are also strings this query does not throw an error but will not find anything. Here is how pagination is used: https://www.prisma.io/docs/prisma-graphql-api/reference/queries-qwe1/#pagination
What I think you want to do is use a filter in the query. For this you can use the where argument. The query would look like this:
getAuditLogsForUser(
where:{AND:[
{createdAt_lte: "2019-01-28T19:31:08.382Z"},
{createdAt_gte: "2019-01-28T17:14:30.047Z"}
]}
) {
id
code { action }
createdAt
}
Here are the docs for filtering: https://www.prisma.io/docs/prisma-graphql-api/reference/queries-qwe1/#filtering

OK so figured out it had to do with the fact that I used "after" and "before" as an argument variable. I have no clue why this completely screws everything up, but it just wont return ANY results if you have this as a argument. Very strange. Must be abstracting some other variable somehow, probably a bug on graphql's end.
As soon as I tried a new variable name, viola, it works.

This is also possible:
const fileData = await prismaClient.fileCuratedData.findFirst({
where: {
fileId: fileId,
createdAt: {
gte: fromdate}
},
});

Related

How can I obtain a document from a Cosmos DB using a field in an array as a filter?

I have a Cosmos DB with documents that look like the following:
{
"name": {
"productName": "someProductName"
},
"identifiers": [
{
"identifierCode": "1234",
"identifierLabel": "someLabel1"
},
{
"identifierCode": "432",
"identifierLabel": "someLabel2"
}
]
}
I would like to write a sql query to obtain an entire document using "identifierLabel" as a filter when searching for the document.
I attempted to write a query based on an example I found from the following blog:
SELECT c,t AS identifiers
FROM c
JOIN t in c.identifiers
WHERE t.identifierLabel = "someLabel2"
However, when the result is returned, it appends the following to the end of the document:
{
"name": {
"productName": "someProductName"
},
"identifiers": [
{
"identifierCode": "1234",
"identifierLabel": "someLabel1"
},
{
"identifierCode": "432",
"identifierLabel": "someLabel2"
}
]
},
{
"identifierCode": "432",
"identifierLabel": "someLabel2"
}
How can I avoid this and get the result that I desire, i.e. the entire document with nothing appended to it?
Thanks in advance.
Using ARRAY_CONTAINS(), you should be able to do something like this to retrieve the entire document, without any need for a self-join:
SELECT *
FROM c
where ARRAY_CONTAINS(c.identifiers, {"identifierLabel":"someLabel2"}, true)
Note that ARRAY_CONTAINS() can search for either scalar values or objects. By specifying true as the third parameter, it signifies searching through objects. So, in the above query, it's searching all objects in the array where identifierLabel is set to "someLabel2" (and then it should be returning the original document, unchanged, avoiding the issue you ran into with the self-join).

WikiJS GraphQL API returning 2 different IDs for the same page

I am using the docker container flavor of WikiJS with a postgres database, out of the box. No tweaks. I am trying to get the API working and it appears that everything works functionally. However, I'm getting wrong ID values for search.
The following query:
query {
pages {
list{
id
path
title
contentType
isPublished
isPrivate
createdAt
updatedAt
}
}
}
Returns the following result:
...
{
"id": 41,
"path": "characters/nicodemus",
"title": "Nicodemus",
"contentType": "markdown",
"isPublished": true,
"isPrivate": false,
"createdAt": "2022-07-26T20:52:26.727Z",
"updatedAt": "2022-08-17T20:31:02.537Z"
},
...
But this query:
query {
pages {
search (query:"nicodemus"){
results{
id
title
path
locale
}
}
}
}
returns this result:
{
"id": "53",
"title": "Nicodemus",
"path": "characters/nicodemus",
"locale": "en"
},
The second result, which is much more efficient than just grabbing every page every time, returns the page id as 53 (incorrect), while all pages returns the page id as 41 (correct).
I am not very familiar with graphql, but I understand the basics and like I said, it seems to be working fine. I don't even know where to start debugging this issue.

AWS Boto3 SDK Access Analyzer list_findings Input Argument Error

I am trying to use the AWS boto3 Python sdk to work with the Access Analyzer api. Specifically the list_findings action. The relevant api documentation is here
https://docs.aws.amazon.com/access-analyzer/latest/APIReference/API_ListFindings.html
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/accessanalyzer.html#AccessAnalyzer.Client.list_findings
According to the documentation the input parameters to this action includes
"sort": {
"attributeName": "string",
"orderBy": "string"
}
The documentation, as far as I can tell, doesn't place any restrictions on what the attributeName can be and therefore it seems that any valid field on the returned findings should be valid input. The structure of the returned findings is described as
{
"findings": [
{
"action": [ "string" ],
"analyzedAt": number,
"condition": {
"string" : "string"
},
"createdAt": number,
"error": "string",
"id": "string",
"isPublic": boolean,
"principal": {
"string" : "string"
},
"resource": "string",
"resourceOwnerAccount": "string",
"resourceType": "string",
"sources": [
{
"detail": {
"accessPointArn": "string"
},
"type": "string"
}
],
"status": "string",
"updatedAt": number
}
],
"nextToken": "string"
}
I would like to sort by the createdAt attribute on the returned findings. For all the fields I have tried they always return the same error
Error has occured in AWS Access Analyzer Integration: An error occurred (ValidationException) when calling the ListFindings operation: Invalid sort.attributeName
An example piece of code I am trying is as follows
client = aws_session(
region='region',
roleArn='roleArn',
roleSessionName='roleSessionName',
roleSessionDuration='roleSessionDuration',
)
kwargs = {
'analyzerArn': 'some_ARN_here'
}
kwargs['sort'] = {
'attributeName': 'createdAt',
'orderBy': 'ASC'
}
response = client.list_findings(**kwargs)
Without the sort arguement the code behaves as expected and returns results. No matter what attribute I use in the sort field it always returns the same error.
How do I know what the valid attributeName's are? What is the correct format for passing parameters in this case? I have not been able to find any other examples online using this particular portion of the boto3 sdk. Any insight would be appreciated.
I am looking to sort the findings in order to retrieve only the most recent. By default the oldest is returned first when specifying maxResults as an arguement.
The answer, and hopefully this saves someone a months time, is that this is not documented correctly anywhere. I had to use my browsers inspector to see the params passed in the request when performing some actions in the AWS UI for Access Analyzer and noticed they were passing UpdatedAt in the attributeName for the sort field.
This subtle distinction was breaking the API call as the U needs to be capitalized in updatedAt when being passed as a parameter. Where is this is documented? Seems nowhere. Not all the fields on findings worked as a sort attribute, such as createdAt. So in order to use the sort field you need to format as such on list_findings
kwargs['sort'] = {
'attributeName': 'UpdatedAt',
'orderBy': 'ASC'
}
This is not representative of how the fields are returned from the API and is not intuitive. The way the parameters are passed to the API are not in the same format as they are received.

id cannot be used in graphQL where clause?

{
members {
id
lastName
}
}
When I tried to get the data from members table, I can get the following responses.
{ "data": {
"members": [
{
"id": "TWVtYmVyOjE=",
"lastName": "temp"
},
{
"id": "TWVtYmVyOjI=",
"lastName": "temp2"
}
] } }
However, when I tried to update the row with 'id' where clause, the console shows error.
mutation {
updateMembers(
input: {
values: {
email: "testing#test.com"
},
where: {
id: 3
}
}
) {
affectedCount
clientMutationId
}
}
"message": "Unknown column 'NaN' in 'where clause'",
Some results from above confused me.
Why the id returned is not a numeric value? From the db, it is a number.
When I updated the record, can I use numeric id value in where clause?
I am using nodejs, apollo-client and graphql-sequelize-crud
TL;DR: check out my possibly not relay compatible PR here https://github.com/Glavin001/graphql-sequelize-crud/pull/30
Basically, the internal source code is calling the fromGlobalId API from relay-graphql, but passed a primitive value in it (e.g. your 3), causing it to return undefined. Hence I just removed the call from the source code and made a pull request.
P.S. This buggy thing which used my 2 hours to solve failed in build, I think this solution may not be consistent enough.
Please try this
mutation {
updateMembers(
input: {
values: {
email: "testing#test.com"
},
where: {
id: "3"
}
}
) {
affectedCount
clientMutationId
}
}

Mongoose query altering object order

I have a query that is generated in my Node backend - if I log it out and run it in Mongo shell then all is fine, however, if I use mongoose to do Model.find(query), then some strange property re-ordering takes place and the query breaks.
The query in question is:
{
"attributes": {
"$all": [
{
"attribute": "an id",
"value": "a value",
"deletedOn": null
},
{
"attribute": "an id again",
"value": "a value",
"deletedOn": null
}
]
}
}
However, the output from mongoose debug is:
users.find({
attributes: {
'$all': [
{
deletedOn: null,
attribute: 'an id',
value: 'a value'
},
{
deletedOn: null,
attribute: 'an id again',
value: 'a value'
}
]
}
},
{ fields: {} }
)
The only change is the shifting of the deletedOn field from last position to first position in the object. This means the query returns no results.
Are there any solutions to this issue?
Object properties in JavaScript are not ordered. You cannot ensure the order of properties on a JavaScript object and different implementations may order them differently. See this answer on a related question for some other info.
The essential key is that from the spec (ECMAScript) we get: "An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method."
There is no "solution", because this is expected behavior. So the real question is, why does the order matter to you? What are you trying to do?
Adding on the previous answer, if order is important to you, you should use array instead of objects.
for example:
"$all": [
[
{"attribute": "an id"},
{"value": "a value"},
{"deletedOn": null},
],
...etc.
]

Resources