In Apigee App Services, can you query an array element? - apigee

Let's say I've got an App Services entity with the following data:
...
times: [
"3/05/2014 18:00:00",
"3/06/2014 16:00:00",
],
...
Using query operators, is there a way to reference a particular numbered element in the array?
I've tried the following:
select * where times.0 > '3/05/2014 18:00:00' //this one returns no data
select * where times[0] > '3/05/2014 18:00:00' //this one fails with a java error
It seems that if there's one element in the array, it works fine just with:
select * where times > '3/05/2014 18:00:00'
...but not if there are more than one (nor if I wanted to check a particular numbered array element).

I was able to query this scenario without a problem using Apigee's Advanced API Services. I have a total of 5 entities in my /items collection, all having the times array. These look like:
{
"uuid": "65d39aba-8df4-11e3-8926-f36d6fff0de6",
"type": "items",
"name": "testItem5",
"created": 1391556657115,
"modified": 1392920493819,
"description": "This is a test item 5.",
"id": "0005",
"metadata": {
"path": "/items/65d39aba-8df4-11e3-8926-f36d6fff0de6"
},
"times": [
"3/05/2014 18:00:00",
"3/06/2014 16:00:00"
]
}
Only 3 of the items have a value > 3/05/2014 18:00:00. When I make the below query:
/items?ql=select%20*%20where%20times%20%3E%20%273/05/2014%2018:00:00%27
or unescaped
/items?ql=select * where times > '3/05/2014 18:00:00'
the 3 items with a value higher than 3/05/2014 18:00:00 return without any problem.

Related

Firestore Pagination : how to set Cursor for startAt using Rest Api

I'm using firebase firestore using Rest API to get data limited by 5 documents only, ordered by a field called LikesCount.
When I want to fetch the next 5 documents I have to use startAt and pass the LikesCount value of the last document from the first 5 documents.
But in this way, it will fetch wrong data when there is another document with the same LikesCount value So I tried and searched a lot about how to pass the last Document id in addition to the LikesCount value But all of them did not work In addition, I tested the pagination using the Web SDK and it was working correctly because you can pass the document snapshot easily, but what does the document snapshot object include? So that we can understand the structure of the Cursor and apply it to the REST API.
I tried to use this method to pass the Document ID as referenceValue
{
"structuredQuery": {
"from": [{
"collectionId": "Users"
}],
"where": {
"compositeFilter": {
"op": "AND",
"filters": []
}
},
"orderBy": [{
"field": {
"fieldPath": "LikesCount"
},
"direction": "DESCENDING"
}],
"startAt":
{ "values": [
{
"integerValue": "6"
},
{
"referenceValue": "projects/myprojectid/databases/(default)/documents/Posts/xEvmJ1LLHwTKVREQfXtX"
}
],
"before": false
},
"limit":5
}
}
But an error will occur : Cursor has too many values.
also, I tried to pass only the referenceValue and it still did not return the correct 5 documents.
Thanks in advance :)
Your orderBy() has 1 field (LikesCount) but your startAt() has 2 fields. I suspect that is the reason for the error message?
Passing the integerValue won't work. If there are 13 results with the value 6, then each time you make the above call you'd get the same first 5 results.
When you say:
I tried only passing the referenceValue and still did not get the correct 5 documents
what documents are you getting? What documents were you expecting to get?

Can't get the desired properties via JsonPath evaluate method

I have a json schema that marks special properties in need of processing and I want to query those via JsonPath.Evaluate.
Here's a part of the schema to illustrate the issue
{
"type": "object",
"properties": {
"period": {
"description": "The period in which the rule applies",
"type": "object",
"properties": {
"start": {
"type": "string",
"format": "date-time"
},
"end": {
"type": "string",
"format": "date-time"
}
},
"required": [
"start"
],
"x-updateIndicatorProperties": [
"start"
]
},
"productType": {
"type": "string"
},
"x-updateIndicatorProperties": [
"productType"
]
}
}
I want to get the the JsonPath of the "x-updateIndicatorProperties" properties, so that I can then query the actual properties to process.
For this example, the expected result would be
[
"$['properties']['x-updateIndicatorProperties']",
"$['properties']['period']['x-updateIndicatorProperties']"
]
I've been trying for a while to get a JsonPath expression that would query these properties.
Currently I'm just iterating all properties and filter them manually :
"$..*"
I've also tried using :
$..['x-updateIndicatorProperties']
This works. But it returns a lot of duplicates. For the example above, I get 5 results instead of the expected 2. Can be demonstrated here : https://json-everything.net/json-path
Assuming I can't influence the schema itself, only the code that traverses it,
can anybody help with an expression to get the expected results or any other way to achieve the same outcome?
The stack is JsonPath 0.2.0, .net 6 and system.text.json.
This was a bug in the library when parsing paths that use a recursive descent (..) into a quoted-property-name selector (['foo']). So it would happen for any path in the form $..['foo'].
I've fixed the issue and released version 0.2.1.

How to convert pipeline().parameters.windowStart to epoch in Azure Data Factory copy pipeline query

I have a timestamp column in DocDb, I would like to query that in Azure Data Factory copy pipeline, which copies DocDb to Azure Data Lake
I would like to
select * from c
where c._ts > '#{pipeline().parameters.windowStart}'
But I got
Errors":["An invalid query has been specified with filters against path(s) that are not range-indexed.
In the DocDb policy, I have
"includedPaths": [
{
"path": "/*",
"indexes": [
{
"kind": "Range",
"dataType": "Number",
"precision": -1
},
{
"kind": "Hash",
"dataType": "String",
"precision": 3
}
]
}
]
I think this should allow _ts int64 to be queried by range.
Where did I go wrong?
Thanks.
I reproduce your issue with your sql and your index policy.
Based on my observation, it seems that the filter is treated as String,not Int.You could remove the ' in your sql and try again,it works for me.
sql:
select * from c
where c._ts > #{pipeline().parameters.windowStart}
Output:
Thanks, #Jay.
I ended up using UDF
function dateTime2Epoch(dateTimeString){
return Math.trunc(new Date(dateTimeString).getTime()/1000);
}
in Cosmos db.
Then in Azure Data Factory query
select * from c
where c._ts >= udf.dateTime2Epoch('#{pipeline().parameters.windowStart}')
and c._ts < udf.dateTime2Epoch('#{pipeline().parameters.windowEnd}')
However, the query seems to be very slow. I will update this when I found more.
Update: Ended up with copying the whole thing.

structure data for different queries

I am learning firebase and trying to find the best way to structure my data.
Use an example of a simple leave application. Employees can submit and view their leaves. Managers can approve leaves.
Option 1
"leaves": [
{
"employee": "pCIUfttSrXQ1dLPDwH7j9GExCkA2",
"date": "2017-03-01",
"status": "pendingApproval",
},
{
"employee": "YSJCAe4wZdYCplA3e0ejMqzQmEF3",
"date": "2017-01-01",
"status": "approved"
}]
With option 1, filtering will be required in both cases:
When employee lists his leave history (filter by "employee")
When manager lists all the pending leaves (filter by "status=pending")
Option 2
"leaves":
{
"pCIUfttSrXQ1dLPDwH7j9GExCkA2" : [
{
"date": "2017-03-01",
"status": "pendingApproval"
}
],
"YSJCAe4wZdYCplA3e0ejMqzQmEF3" : [
{
"date": "2017-01-01",
"status": "approved"
}
]
}
With option 2, no filtering is required when employee lists his leave history, but filtering is required (and I don't know how) for manager to list pending leaves.
What should be the right way to structure the data? And if it's option 2, how would we filter the pending leaves for all employees?
Use the second option;
For the manager to filter through the pending queries , use:
FIRDatabase.database().reference().child("leaves").queryOrdered(byChild: "status").queryEqual(toValue: "pending").observeSingleEvent(of: .value, with: {(Snapshot) in
print(Snapshot.value!)
// If you have multiple pending request you gotta loop through them
// using for loop, access them as separate entity and operate on them
})

How to get notifications that have Edge date property greater than last visited date in Titan using Gremlin?

I'm having user vertices which have incoming Notification edges as follows:
code am using to get notifications
g.v(17929472).outE('Notification')
Response I'm getting :
{
"success": true,
"results": [
{
"Type": "UserReaction",
"PostedDate": "2016-04-15T09:03:42.8391677Z",
"NotificationInitiatedByVertexId": "2304",
"_id": "c7bb4-aoagw-sgl-aoao0",
"_type": "edge",
"_outV": 17929472,
"_inV": 17929728,
"_label": "Notification"
}
],
"version": "2.5.0",
"queryTime": 15.310751
}
Whenever user view the notification i'm saving the last seen date and want to use that date to get all notification that is present after that date.
I've tried :
g.v((5124096).outE).outE.has('PostedDate',T.gte, 2016-04-15T07:52:31.6979843Z).inV
but it is giving error.
PostedDate appears to be returned as a String. Consider defining PostedDate in your schema definition as a Long instead, and then do the T.gte comparison with a Long value.

Resources