Access Nested Objects using Painless for Elasticsearch/Opensearch Alerting to Create Trigger Condition - opensearch

I tried creating Trigger condition in Monitor in Opensearch.I was trying to extract fields present in _source which is giving error "reason" : "Illegal list shortcut value [_source].".
DSL Extraction Query-
{
"size": 1,
"sort": {"Date" : "desc" },
"query": {
"bool": {
"filter": [
{
"range": {
"Date": {
"from": "{{period_end}}||-3d",
"to": "{{period_end}}",
"include_lower": true,
"include_upper": true,
"format": "epoch_millis",
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"aggregations": {
"metric": {
"avg": {
"field": "difference"
}
}
}
}
Output-
{
"_shards": {
"total": 4,
"failed": 0,
"successful": 4,
"skipped": 2
},
"hits": {
"hits": [
{
"_index": "reliance_cal_spread",
"_source": {
"symbol": "RELIANCE",
"std_dev": 2.4,
"upper_range": 10.3,
"current_month_close": 2536.3,
"mean": 7.9,
"weekday": "Tuesday",
"difference": 3,
"Date": "2022-06-28T00:00:00",
"next_month_close": 2539.3,
"lower_range": 5.5
},
"_id": "E2-cqoEB0vMP3J-sGCIB",
"sort": [
1656374400000
],
"_score": null
}
],
"total": {
"value": 2,
"relation": "eq"
},
"max_score": null
},
"took": 8,
"timed_out": false,
"aggregations": {
"metric": {
"value": 2.799999952316284
}
}
}
Trigger Condition-
return ctx.results[0].aggregations.metric.value == null ? false :ctx.results[0].hits.hits._source.difference > 6
Error-
{
"type" : "script_exception",
"reason" : "runtime error",
"script_stack" : [
"return ctx.results[0].aggregations.metric.value == null ? false :ctx.results[0].hits.hits._source.difference > 6",
" ^---- HERE"
],
"script" : "return ctx.results[0].aggregations.metric.value == null ? false :ctx.results[0].hits.hits._source.difference > 6",
"lang" : "painless",
"position" : {
"offset" : 89,
"start" : 0,
"end" : 112
},
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "Illegal list shortcut value [_source]."
}
}
While I am able to extract other conditions such as-aggregations.metric.value and hits.total.value.
Trigger Condition
return ctx.results[0].aggregations.metric.value == null ? false :ctx.results[0].aggregations.metric.value < 6
Trigger Condition Response-
True

Related

How to sum values using unwind in MongoDB with Spring Data

When using unwind("items") each item produces a duplicate line. This leads to revenue being counted as many times as there are items.
Example: Someone buys 1 item of A and 1 item of B, resulting in a cummulative value of 10. Unwind now inserts a row for each item, leading to a sum(cummulative) of 20.
I tried grouping the elements directly after unwind but have not managed to get it to work properly.
How can I sum each array element without duplication every other value?
I have this data structure
{
"_id": {
"$binary": "VEE6CsjHPvjzS2JYso7mnQ==",
"$type": "3"
},
"sequentialId": {
"$numberLong": "1"
},
"date": "2022-02-04",
"invoiceTotal": {
"$numberDecimal": "9.85"
},
"vatTotal": {
"$numberDecimal": "0"
},
"vatPercentage": {
"$numberDecimal": "19.00"
},
"invoiceNumber": "1111111",
"type": "ELEKTRONISCH",
"aktivkonto": 2800,
"passivkonto": 5200,
"buyerEmail": "",
"username": "",
"shop": "",
"externalId": "",
"shipped": false,
"actualShippingCost": {
"$numberDecimal": "1"
},
"filename": "",
"isReported": false,
"deliveryCostTotal": {
"$numberDecimal": "4.35"
},
"items": [
{
"lineItemId": "",
"amount": "1",
"sku": "A123123",
"title": "",
"priceTotal": {
"$numberDecimal": "4.50"
},
"vatTotal": {
"$numberDecimal": "0"
},
"hardwareCostPerPiece": {
"$numberDecimal": "0.22"
},
"hardwareCostTotal": {
"$numberDecimal": "0.22"
}
},
{
"lineItemId": "",
"amount": "1",
"sku": "B212312",
"title": "",
"priceTotal": {
"$numberDecimal": "1.00"
},
"vatTotal": {
"$numberDecimal": "0"
},
"hardwareCostPerPiece": {
"$numberDecimal": "0.22"
},
"hardwareCostTotal": {
"$numberDecimal": "0.22"
}
}
],
"packagingCost": {
"$numberDecimal": "0.15"
},
"hasInvoiceSent": false,
"tenant": "you!",
"createdAt": {
"$date": "2022-02-04T15:23:40.716Z"
},
"modifiedAt": {
"$date": "2022-02-04T15:23:40.716Z"
},
"_class": "_.RevenueEntity"
}
and this query
fun sumAllByWeeklyAndTenant(tenant: String): Flux<DashboardRevenue> {
val aggregation = newAggregation(
match(findByTenant(tenant)),
unwind("items"),
group("invoiceNumber")
.sum("items.hardwareCostTotal").`as`("hardwareCostTotal"),
project()
.andExpression("year(createdAt)").`as`("year")
.andExpression("week(createdAt)").`as`("week")
.andInclude(bind("hardwareCostTotal", "items.hardwareCostTotal"))
.andInclude(
"invoiceTotal",
"vatTotal",
"actualShippingCost",
"packagingCost",
"marketplaceFeesTotal",
"tenant"
),
group("year", "week", "tenant")
.sum("invoiceTotal").`as`("umsatz")
.sum("actualShippingCost").`as`("portokosten")
.sum("packagingCost").`as`("verpackung")
.sum("marketplaceFeesTotal").`as`("marketplaceFees")
.sum("hardwareCostTotal").`as`("hardwareCost")
.sum("vatTotal").`as`("vatTotal")
.count().`as`("numberOfInvoices"),
sort(Sort.Direction.DESC, "year", "week"),
limit(8),
sort(Sort.Direction.ASC, "year", "week")
)
return reactiveMongoTemplate
.aggregate(aggregation, "revenue", DashboardRevenue::class.java)
.toFlux()
}
Using the data above the query results in
[
{
"_id": {
"year": 2022,
"month": 2,
"week": 0,
"tenant": "einsupershop"
},
"umsatz": 19.70,
"portokosten": 2,
"verpackung": 0.30,
"marketplaceFees": 3.42,
"hardwareCost": 0.22,
"vatTotal": 0,
"numberOfInvoices": 2
}
]
Where the expected value is "invoiceTotal": { "$numberDecimal": "9.85" }

Aggregate and grouping in Mongo

How do I get a summary count in Mongo. I have the following record structure and I would like to get a summary by date and status
{
"_id": "1",
"History": [
{
"id": "11",
"message": "",
"status": "send",
"resultCount": 0,
"createdDate": "",
"modifiedDate": ""
},
{
"id": "21",
"message": "",
"status": "skipped",
"resultCount": 0,
"createdDate": "",
"modifiedDate": ""
}
]
}
This is what I would like..
date x
status :
count : nn
This is my Mongo structure
Let's assume you have the following data in 'history' collection:
{
"_id": "1",
"History": [
{
"id": "21",
"message": "",
"status": "send",
"resultCount": 0,
"createdDate": "date1",
"modifiedDate": ""
},
{
"id": "22",
"message": "",
"status": "skipped",
"resultCount": 0,
"createdDate": "date1",
"modifiedDate": ""
},
{
"id": "23",
"message": "",
"status": "skipped",
"resultCount": 0,
"createdDate": "date2",
"modifiedDate": ""
},
{
"id": "24",
"message": "",
"status": "skipped",
"resultCount": 0,
"createdDate": "date2",
"modifiedDate": ""
}
]
}
You can design your query in the following way to get the desired summary.
db.history.aggregate([
{
$unwind:"$History"
},
{
$group:{
"_id":{
"createdDate":"$History.createdDate",
"status":"$History.status"
},
"createdDate":{
$first: "$History.createdDate"
},
"status":{
$first:"$History.status"
},
"count":{
$sum:1
}
}
},
{
$group:{
"_id":"$createdDate",
"createdDate":{
$first:"$createdDate"
},
"info":{
$push:{
"status":"$status",
"count":"$count"
}
}
}
},
{
$project:{
"_id":0
}
}
]).pretty()
It would result in the following:
{
"createdDate" : "date1",
"info" : [
{
"status" : "skipped",
"count" : 1
},
{
"status" : "send",
"count" : 1
}
]
}
{
"createdDate" : "date2",
"info" : [
{
"status" : "skipped",
"count" : 2
}
]
}
Aggregation stages details:
Stage I: The 'History' array is unwinded i.e. the array would be split and each element would create an individual document.
Stage II: The data is grouped on the basis of 'createdDate' and 'status'. In this stage, the count of status is also calculated.
Stage III: The data is further grouped on the basis of 'createdDate'
only
Stage IV: Eliminating non-required fields from the result

Acumatica Rest API to get sales order with line item detail

I was doing a demo and could easily create and retrieve orders but was not able to get the expand parameter to work
For example
I created order SO003615 with:
URI http://localhost/Acumatica6/entity/Default/6.00.001/SalesOrder
{
"OrderType": { value: "SO" },
"CustomerID" : { value : "ACTIVESTAF" } ,
"LocationID" : { value : "MAIN" },
"Description" : { value : "Sample Order"},
"Details" :
[
{
"InventoryID" : {value: "AACOMPUT01"},
"Quantity" : {value: 2},
"UOM" : {value: "EA"},
"UnitPrice" : {value: 1000.99}
},
{
"InventoryID" : {value: "AALEGO500"},
"Quantity" : {value: 1}
}
]
}
Then I tried to get order with
URI http://localhost/Acumatica6/entity/Default/6.00.001/SalesOrder/SO/SO003615?expand=Details
But the line items are not in the result. What am I missing?
{
"id": "37c15980-f71d-4496-882d-6e05e4a50061",
"rowNumber": 1,
"note": "",
"BillingAddressOverride": {
"value": false
},
"BillingContactOverride": {
"value": false
},
"CreditHold": {
"value": false
},
"Currency": {
"value": "USD"
},
"CustomerID": {
"value": "ACTIVESTAF"
},
"CustomerOrder": {},
"Date": {
"value": "2017-03-16T00:00:00-04:00"
},
"Description": {
"value": "Sample Order 6"
},
"DestinationWarehouseID": {},
"ExternalReference": {},
"Hold": {
"value": false
},
"IsTaxValid": {
"value": false
},
"LastModified": {
"value": "2017-03-17T01:05:56.74-04:00"
},
"LocationID": {
"value": "MAIN"
},
"NewCard": {
"value": false
},
"OrderedQty": {
"value": 3
},
"OrderNbr": {
"value": "SO003615"
},
"OrderTotal": {
"value": 2101.98
},
"OrderType": {
"value": "SO"
},
"PaymentCardIdentifier": {},
"PaymentMethod": {
"value": "CHECK"
},
"PaymentRef": {},
"PreferredWarehouseID": {},
"Project": {
"value": "X"
},
"RequestedOn": {
"value": "2017-03-16T00:00:00-04:00"
},
"ShippingAddressOverride": {
"value": false
},
"ShippingContactOverride": {
"value": false
},
"ShipVia": {},
"Status": {
"value": "Open"
},
"TaxTotal": {
"value": 0
},
"custom": {},
"files": []
}
It is $expand, not expand. Try using the following
http://localhost/Acumatica6/entity/Default/6.00.001/SalesOrder/SO/003615?$expand=Details

Mongodb query select embedded document

I have following Mongodb document. Would like to fetch document where participant = 'xxx' and (message.touserid = 'xxx' or message.fromuserid = 'xxx').
I am using following query but it is returning all messages instead of just one. Could you please let me know how to achieve this result?
{ "$and" : [ { "participants" : { "$regex" : "56d314a8e4b04d7f98cfd0c6"} , "$or" : [ { "messages.touserId" : "56d314a8e4b04d7f98cfd0c6"} , { "messages.formuserId" : "56d314a8e4b04d7f98cfd0c6"}]}]} fields: { "_id" : "0" , "product" : "0" , "participants" : "0" , "messages" : "0"}
{
"_id": {
"$oid": "574eb878027520c2158268d6"
},
"_class": "com.idearealty.product.shopchat.persistence.model.Discussion",
"participants": "56d314a8e4b04d7f98cfd0c6,56d5d48ee4b0cc330f512a47,56d9d599e4b0cc330f512aaa,57130299e4b08c554c1092c7,56841002eceefce22f455c7f",
"messages": [
{
"_id": {
"$oid": "574eb874027520c2158268d2"
},
"formuserId": "56841002eceefce22f455c7f",
"fromuser": "9674642375",
"touserId": "56d314a8e4b04d7f98cfd0c6",
"touser": "debopam_r",
"message": "Creating Discussion",
"isMute": false,
"index": 1,
"createDate": {
"$date": "2016-06-01T10:27:00.500Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:00.501Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
},
{
"_id": {
"$oid": "574eb875027520c2158268d3"
},
"formuserId": "56841002eceefce22f455c7f",
"fromuser": "9674642375",
"touserId": "56d5d48ee4b0cc330f512a47",
"touser": "Raushan",
"message": "Creating Discussion",
"isMute": false,
"index": 2,
"createDate": {
"$date": "2016-06-01T10:27:01.295Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:01.295Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
},
{
"_id": {
"$oid": "574eb875027520c2158268d4"
},
"formuserId": "56841002eceefce22f455c7f",
"fromuser": "9674642375",
"touserId": "56d9d599e4b0cc330f512aaa",
"touser": "anirbanshop1",
"message": "Creating Discussion",
"isMute": false,
"index": 3,
"createDate": {
"$date": "2016-06-01T10:27:01.962Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:01.962Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
},
{
"_id": {
"$oid": "574eb876027520c2158268d5"
},
"formuserId": "56841002eceefce22f455c7f",
"fromuser": "9674642375",
"touserId": "57130299e4b08c554c1092c7",
"touser": "dummyshop",
"message": "Creating Discussion",
"isMute": false,
"index": 4,
"createDate": {
"$date": "2016-06-01T10:27:02.574Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:02.574Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
}
],
"messageCount": 4,
"createDate": {
"$date": "2016-06-01T10:27:04.041Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:04.041Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
}
As this is a complex match on elements - $elemMatch cannot be used in this case,
so aggregation framework is a helper.
var match = {
$match : {
participants : /56d314a8e4b04d7f98cfd0c6/
}
}
var unwind = {
$unwind : "$messages"
}
var matchSecond = {
$match : {
$or : [{
"messages.touserId" : "56d314a8e4b04d7f98cfd0c6"
}, {
"messages.formuserId" : "56d314a8e4b04d7f98cfd0c6"
}
]
}
}
var projection = {
$project : {
_id : 0,
messages : 1
}
}
db.deb.aggregate([match, unwind, matchSecond, projection])
and output:
{
"messages" : {
"_id" : {
"oid" : "574eb874027520c2158268d2"
},
"formuserId" : "56841002eceefce22f455c7f",
"fromuser" : "9674642375",
"touserId" : "56d314a8e4b04d7f98cfd0c6",
"touser" : "debopam_r",
"message" : "Creating Discussion",
"isMute" : false,
"index" : 1.0,
"createDate" : {
"date" : "2016-06-01T10:27:00.500Z"
},
"lastModifiedDate" : {
"date" : "2016-06-01T10:27:00.501Z"
},
"createdBy" : "9674642375",
"lastModifiedBy" : "9674642375"
}
}

Mongo returning an array element

I have the following JSON document in my mongoDB which I added with mingoimport.
I am trying to return a single element from the questions array where theQuestion equals "q1".
{
"questions": [
{
"questionEntry": {
"id": 1,
"info": {
"seasonNumber": 1,
"episodeNumber": 1,
"episodeName": "Days Gone Bye"
},
"questionItem": {
"theQuestion": "q1",
"attachedElement": {
"type": 1,
"value": ""
}
},
"options": [
{
"type": 1,
"value": "o1"
},
{
"type": 1,
"value": "o1"
}
],
"answer": {
"questionId": 1,
"answer": 1
},
"metaTags": [
"Season 1",
"Episode 1",
"Rick Grimmes"
]
}
},
{
"questionEntry": {
"id": 1,
"info": {
"seasonNumber": 1,
"episodeNumber": 1,
"episodeName": "Days Gone Bye"
},
"questionItem": {
"theQuestion": "q2",
"attachedElement": {
"type": 1,
"value": ""
}
},
"options": [
{
"type": 1,
"value": "o2"
},
{
"type": 1,
"value": "o2"
}
],
"answer": {
"questionId": 1,
"answer": 1
},
"metaTags": [
"Season 1",
"Episode 1",
"Rick Grimmes",
"Glenn Rhee"
]
}
}
]
}
I ran the query db.questions.find({"questions.questionEntry.questionItem.theQuestion" : "q1"}) but this retruned the whole document (both questionEntry's in question array!
I have tried db.questions.find({"questions.questionEntry.questionItem.theQuestion" : "q1"}, _id:0," questions.questionItem": {$elemMatch : {theQuestion: "q1"}}})
But get the following error:
Error: error: {
"$err" : "Can't canonicalize query: BadValue Cannot use $elemMatch projection on a nested field.", "code" : 17287
Is there a way I could limit the result to just the array element which contains it?
Thanks
db.questions.find({},{"questions.questionEntry.questionItem.theQuestion" : "q1"});
or
db.questions.find({"questions.questionEntry.questionItem.theQuestion" : "q1"},{'questions.$':1});
please try these.
If you want to use $elemMatch the query should be:
db.questions.find(
{"questions.questionEntry.questionItem.theQuestion" : "q1"},
{
'_id':0,
"questions": {
$elemMatch : {"questionEntry.questionItem.theQuestion": "q1"}
}
}
)