how to define a resolver in appsync to get a range of data between a particular dates in graphQL - graphql

{
"version": "2018-05-29",
"operation": "Query",
"index": "sportLeague",
"query": {
"expression": "sportIdLeagueId = :sportIdLeagueId and gsSK = :gsSK",
"expressionValues": {
#set( $sportIdLeagueId = $util.dynamodb.toDynamoDBJson("fixture#${ctx.args.input.sportId}#${ctx.args.input.leagueId}") )
":sportIdLeagueId": $sportIdLeagueId,
}
},
"filter" : {
"expression" : "between(#title, :title)",
"expressionNames" : {
"#startDateUtc" : "startDateUtc"
}
"expressionValues" : {
":start" : $util.dynamodb.toDynamoDBJson($ctx.args.input.startDateUtc)
}
}
}
i need a between condition to satisfy the requirement
requirement: get data between two dates i.e start date and end date

You attribute names and values need to match what is in your expression. (:title needs to have a corresponding value in expressionNames and expressionValues)
Also the between operator syntax is BETWEEN :startDateUtc AND :endDateUtc
There is a tutorial for using DynamoDB Query in AppSync:
https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-dynamodb-resolvers.html#setting-up-the-allpostsbyauthor-resolver-ddb-query
DynamoDB expressions:
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html

Related

Use query result as parameter for another query in Elasticsearch DSL

I'm using Elasticsearch DSL, I'm trying to use a query result as a parameter for another query like below:
{
"query": {
"bool": {
"must_not": {
"terms": {
"request_id": {
"query": {
"match": {
"processing.message": "OUT Followup Synthesis"
}
},
"fields": [
"request_id"
],
"_source": false
}
}
}
}
}
}
As you can see above I'm trying to search for sources that their request_id is not one of the request_idswith processing.message equals to OUT Followup Synthesis.
I'm getting an error with this query:
Error loading data [x_content_parse_exception] [1:1660] [terms_lookup] unknown field [query]
How can I achieve my goal using Elasticsearch DSL?
Original question extracted from the comments
I'm trying to fetch data with processing.message equals to 'IN Followup Sythesis' with their request_id doesn't appear in data with processing.message equals to 'OUT Followup Sythesis'. In SQL language:
SELECT d FROM data d
WHERE d.processing.message = 'IN Followup Sythesis'
AND d.request_id NOT IN (SELECT request_id FROM data WHERE processing.message = 'OUT Followup Sythesis');
Answer: generally speaking, neither application-side joins nor subqueries are supported in Elasticsearch.
So you'll have to run your first query, take the retrieved IDs and put them into a second query — ideally a terms query.
Of course, this limitation can be overcome by "hijacking" a scripted metric aggregation.
Taking these 3 documents as examples:
POST reqs/_doc
{"request_id":"abc","processing":{"message":"OUT Followup Synthesis"}}
POST reqs/_doc
{"request_id":"abc","processing":{"message":"IN Followup Sythesis"}}
POST reqs/_doc
{"request_id":"xyz","processing":{"message":"IN Followup Sythesis"}}
you could run
POST reqs/_search
{
"size": 0,
"query": {
"match": {
"processing.message": "IN Followup Sythesis"
}
},
"aggs": {
"subquery_mock": {
"scripted_metric": {
"params": {
"disallowed_msg": "OUT Followup Synthesis"
},
"init_script": "state.by_request_ids = [:]; state.disallowed_request_ids = [];",
"map_script": """
def req_id = params._source.request_id;
def msg = params._source.processing.message;
if (msg.contains(params.disallowed_msg)) {
state.disallowed_request_ids.add(req_id);
// won't need this particular doc so continue looping
return;
}
if (state.by_request_ids.containsKey(req_id)) {
// there may be multiple docs under the same ID
// so concatenate them
state.by_request_ids[req_id].add(params._source);
} else {
// initialize an appendable arraylist
state.by_request_ids[req_id] = [params._source];
}
""",
"combine_script": """
state.by_request_ids.entrySet()
.removeIf(entry -> state.disallowed_request_ids.contains(entry.getKey()));
return state.by_request_ids
""",
"reduce_script": "return states"
}
}
}
}
which'd return only the correct request:
"aggregations" : {
"subquery_mock" : {
"value" : [
{
"xyz" : [
{
"processing" : { "message" : "IN Followup Sythesis" },
"request_id" : "xyz"
}
]
}
]
}
}
⚠️ This is almost guaranteed to be slow and goes against the suggested guidance of not accessing the _source field. But it also goes to show that subqueries can be "emulated".
💡 I'd recommend to test this script on a smaller set of documents before letting it target your whole index — maybe restrict it through a date range query or similar.
FYI Elasticsearch exposes an SQL API, though it's only offered through X-Pack, a paid offering.

Run a subquery for each of the filtered elasticsearch documents

I have an index named employees with the following structure:
{
id: integer,
name: text,
age: integer,
cityId: integer,
resumeText: text <--------- parsed resume text
}
I want to search employees with certain criteria e.g having age > 40, resumeText contains a specific skill or employee belongs to a certain city etc, and have the following query for so far requirement:
{
query:{
bool:{
should:[
{
term:{
cityId:2990
},
{
match:{
resumeText:"marketing"
},
{
match:{
resumeText:"critical thinking"
}}}
],
filter:{
range:{
age:{
gte:40
}}}}}
}
This gives me expected results but i want to know also among the returned documents/employees which are the ones whose resumeText contains the mentioned skills. e.g in the response, I want to get documents having mentioned that this document had matched "critical thinking" , this employee had matched both the skills and this employee didn't match any skills (as it was returned based on other filters)
What changes do i need to do to get the desired results:
can aggregation help?
can we rum a script for EACH filtered document to compute desired result (sub query for each document)?
any other approach?
Yes, You can use aggregation.
Refer this
You can bucket like how many resumes are matching each skill you are looking for.
GET employees/_search
{
"size": 0,
"aggs" : {
"messages" : {
"filters" : {
"filters" : {
"marketing_resume_count" : { "match" : { "resumeText" : "marketing" }},
"thinking_resume_count" : { "match" : { "resumeText" : "thinking" }}
}
}
}
}
}
To extend to your use case:
You can add query section to the query as below
GET employees/_search
{
"size": 0,
"query":{
"match":{
"region":"AM"
}
},
"aggs" : {
"messages" : {
"filters" : {
"filters" : {
"marketing_resume_count" : { "match" : { "resumeText" : "marketing" }},
"thinking_resume_count" : { "match" : { "resumeText" : "thinking" }}
}
}
}
}
}
You can use range query to handle gte and let conditions. You can refer this for range query example. This can be used in place of query section.

How to search through nested array and retreive only matched elements with mongo and springdata [duplicate]

This question already has answers here:
Find in Double Nested Array MongoDB
(2 answers)
Spring data Match and Filter Nested Array
(1 answer)
Closed 3 years ago.
I'm looking to search into my collection and retreive only element who matched Criteria.
Here is my collection :
{
"_id" : "id",
"name" : "test",
"groupUsers" : [
{
"name" : "blabla",
"toys" : [
{
"createdAt" : ISODate("2019-10-30T12:59:41.409Z"),
},
{
"createdAt" : ISODate("2019-11-30T12:59:10.409Z"),
},
{
"createdAt" : ISODate("2019-12-30T12:59:12.409Z"),
}
],
"createdAt" : ISODate("2019-10-30T12:33:39.036Z")
},
{
"name" : "blabla2",
"toys" : [
{
"createdAt" : ISODate("2019-10-32T12:59:41.409Z"),
},
{
"createdAt" : ISODate("2019-11-30T12:59:56.409Z"),
},
{
"createdAt" : ISODate("2019-12-30T12:59:15.409Z"),
}
],
"createdAt" : ISODate("2019-10-32T12:33:39.036Z")
}
],
}
I want to retreive the whole collection but it depends when the user was added to the group for example, user blabla2 (in the example above) will only get the whole group but with only the two last toys of the first user in the response.
Anyway, I guess it's something really basic but I don't know why I can't figure it out.
What I'm Doing
I'm doing a first query to get the current user and get when he was added in the group (notice that the date gets converted into java Date Util here).
Aggregation groupAgg = newAggregation(match(Criteria.where("_id").is(groupId).and("groupUsers.userId").is(userId)));
GroupUser groupUser = mongoTemplate.aggregate(groupAgg, Group.class, GroupUser.class).getUniqueMappedResult();
In a second query, I want to get the whole document but only with the Criteria that I define before.
MatchOperation matchedGroup = match(new Criteria("_id").is(groupId));
MatchOperation matchedToys = match(
new Criteria("groupUsers.toys.createdAt").gte(groupUser.getCreatedAt()));
Aggregation aggregation = newAggregation(matchedGroup, matchedToys);
AggregationResults<Group> result = mongoTemplate.aggregate(aggregation, Group.class, Group.class);
Group group = result.getUniqueMappedResult();
This query doesn't work, and I'm looking to something like even if there is no match (for example, none toys has been created yet), it still return the group basic response and not null.
Maybe I need to unwind the nested array ?
Any help is appreciate. I'm using spring data.
Try this query
db.testers.aggregate([
{
$addFields:{
"groupUsers":{
$map:{
"input":"$groupUsers",
"as":"doc",
"in":{
$mergeObjects:[
"$$doc",
{
"toys":{
$filter:{
"input":"$$doc. toys",
"as":"sn",
"cond": {
"$and": [
{ "$gte": [ "$$sn.createdAt", ISODate('2015-06-17T10:03:46.000Z') ] },
]
}
}
}
}
]
}
}
}
}
}
]).pretty()

How do I write an OR query in Kibana (ElasticSearch)?

Using ElasicSearch's JSON Query DSL through Kibana, how do I retrieve all documents which have:
messageTemplate equals My message
or
level equals Error
You have to use a Bool query for that :
... If the bool query is a filter context or has neither must or filter then at least one of the should queries must match a document for it to match the bool query
POST <your_index>/_search
{
"query": {
"bool": {
"should": [
{ "match_phrase" : { "messageTemplate" : "My message" } },
{ "term" : { "level" : "Error" } }
]
}
}
}
Alternatively, you could type in the Kibana search bar:
messageTemplate:"My message" || level:"Error"
or
messageTemplate:"My message" OR level:"Error"

Combination of and or elasticsearch

How to write query for following condition in elasticsearch
Select * from table1 where (cnd1 or cond2) and (cnd3)
My cond2 value is from nested object . My json object is below
details={ "name"="name1",
"address":"{
"city":"city1"
}"
}
I need to take city from above object
details.address.city
Is above syntax is right , if not how to get value of second object city.
{
"bool" : {
"must" : cond3,
"should" : [
cond1,
cond2
],
"minimum_should_match" : 1
}
}
go through this link for more info https://www.elastic.co/guide/en/elasticsearch/reference/2.3/query-dsl-bool-query.html
You can easily create a conditional queries with Elasticsearch. But there is some weird situation of your data section.
details={ "name"="name1",
"address":"{
"city":"city1"
}"
}
Elasticsearh save your data as a json object, but you should give your data as a json. In this section, there is an object, you try to sent. Let us examine:
There is a name attribute of detail object, it is a string. And also there is a address attribute, and it is a string too. It should be an object which has to include a city attribute if you want to reach this object via details.address.city. Now we try to fix:
{
"id":...,
...
"details": {
"name": "name1",
"address": {
"city": "city1"
}
}
}
In this case, I remove double quotation marks of details object. Now, you can reach city attribute of json as a json object. Now, we create a query to reach cities:
{
"query": {
"bool": {
"must": {
"term": {
"your-json-attribute": "???"
}
},
"should": [
{
"term": {
"your-json-attribute": "???"
}
},
{
"term": {
"your-json-attribute": "???"
}
}
]
}
}
}
I use term query but there is lots of another query types. You can check them on documentation. But for And and Or, you can use bool query. Check https://www.elastic.co/guide/en/elasticsearch/reference/2.0/query-dsl-bool-query.html

Resources