Druid query does not return case Insensitive results for count aggregation - count

Ideally, I need to get the count of how many times "London" is used in the city name. But the query returns different values for "london" and "London" and "LoNdOn" and so on.
I have tried using Case Insensitive as an option, but it doesn't give me the required result.
Here's my query,
{
"queryType": "topN",
"dataSource": "wikiticker",
"dimension":"cityName",
"granularity": "ALL",
"metric": "count",
"threshold": 10,
"filter":
{
"type": "search",
"dimension": "cityName",
"query": {
"type": "insensitive_contains",
"value": "london",
}
},
"aggregations": [
{
"type": "longSum",
"name": "count",
"fieldName": "count"
}
],
"intervals": ["2014-10-01T00:00:00.000Z/2016-10-07T00:00:00.000Z"]
}
And here's my result :
[ {
"timestamp" : "2015-09-12T00:46:58.771Z",
"result" : [ {
"count" : 21,
"cityName" : "London"
},
{
"count" : 10,
"cityName" : "New London"
},
{
"count" : 3,
"cityName" : "london"
},
{
"count" : 1,
"cityName" : "LoNdon"
},
{
"count" : 1,
"cityName" : "LondOn"
} ]
} ]
I should get something like:
[ {
"timestamp" : "2015-09-12T00:46:58.771Z",
"result" : [ {
"count" : 26,
"cityName" : "London"
},
{
"count" : 10,
"cityName" : "New London"
} ]
} ]

Use the filtered aggregator:
A filtered aggregator wraps any given aggregator, but only aggregates the values for which the given dimension filter matches.
{
"type" : "filtered",
"filter" : {
"type" : "search",
"dimension" : cityName,
"query": {
"type":"contains",
"value":"london"
}
},
"aggregator" : {
"type": "count",
"name": "Total Count of the Name London"
}
}
References
Druid Documentation: Filtered Aggregator

Related

How can I duplicate multiple times an existing object within a JSON array using jq?

I have the following json file:
{
"actions": [
{
"values": "test",
"features": [
{
"v1": 100,
"v2": {
"dates": [
"2020-04-08 06:58:26",
"2020-04-08 06:58:26"
]
}
}
]
}
]
}
I would like to append n-times the object within the "actions" array to the end of it, creating n+1 total objects.
Expected output if n=2:
{
"actions": [
{
"values": "test",
"features": [
{
"v1": 100,
"v2": {
"dates": [
"2020-04-08 06:58:26",
"2020-04-08 06:58:26"
]
}
}
]
},
{
"values": "test",
"features": [
{
"v1": 100,
"v2": {
"dates": [
"2020-04-08 06:58:26",
"2020-04-08 06:58:26"
]
}
}
]
},
{
"values": "test",
"features": [
{
"v1": 100,
"v2": {
"dates": [
"2020-04-08 06:58:26",
"2020-04-08 06:58:26"
]
}
}
]
}
]
}
I found this answer [How can I duplicate an existing object within a JSON array using jq? however it only works with one element at the end.
You can just use a reduce() function with range() together to create the index to include the object at.
jq --arg n 2 'reduce range(0, ($n|tonumber)) as $d (.; .actions[$d+1] += .actions[0] )' json

What is the JsonPath expression for selecting an object based on sub-object values?

I need to be able to select elements within a JSON document based on the values in sub-elements which, unfortunately, reside in a list of key-value pairs (this is the structure I have to work with). I'm using Jayway 2.4.0.
Here is the JSON document:
{
"topLevelArray": [
{
"elementId": "Elem1",
"keyValuePairs": [
{
"key": "Length",
"value": "10"
},
{
"key": "Width",
"value": "3"
},
{
"key": "Producer",
"value": "alpha"
}
]
},
{
"elementId": "Elem2",
"keyValuePairs": [
{
"key": "Length",
"value": "20"
},
{
"key": "Width",
"value": "8"
},
{
"key": "Producer",
"value": "beta"
}
]
},
{
"elementId": "Elem3",
"keyValuePairs": [
{
"key": "Length",
"value": "15"
},
{
"key": "Width",
"value": "5"
},
{
"key": "Producer",
"value": "beta"
}
]
}
]
}
Here is the JsonPath I thought would do the trick:
$..topLevelArray[ ?( #.keyValuePairs[ ?(#.key=='Producer' && #.value=='beta') ] ) ]
and
$.topLevelArray[ ?( #.keyValuePairs[ ?(#.key=='Producer' && #.value=='beta') ] ) ]
Unfortunately, both are returning everything in the list, including the entry with Producer of 'alpha'. Thx in advance.

DevExtreme: Return Object from Spring Rest Api does not bind with dxDataGrid

Could any one help me how could I bind data object with DevExtreme's dxDataGrid using customstore.
My DTO is like:
[
data: {...},
totalCount: 100,
summary: [10,20,30]
]
But when i bind the data with dxDataGrid it just bind data but not totalCount.
I have found a solution for my problem.
[remoteOperations]="true"
I need remoteOperations = true to bind the totalCount along with data fetched from the server.
You don't need to send a totalCount, you have to use the summary section istead, look at this sample
$("#gridContainer").dxDataGrid({
dataSource: orders,
keyExpr: "ID",
showBorders: true,
selection: {
mode: "single"
},
columns: [{
dataField: "OrderNumber",
width: 130,
caption: "Invoice Number"
}, {
dataField: "OrderDate",
dataType: "date",
width: 160
},
"Employee", {
caption: "City",
dataField: "CustomerStoreCity"
}, {
caption: "State",
dataField: "CustomerStoreState"
}, {
dataField: "SaleAmount",
alignment: "right",
format: "currency"
}
],
summary: {
totalItems: [{
column: "OrderNumber",
summaryType: "count"
}]
}
});
Data Source
var orders = [{
"ID" : 1,
"OrderNumber" : 35703,
"OrderDate" : "2014-04-10",
"SaleAmount" : 11800,
"Terms" : "15 Days",
"TotalAmount" : 12175,
"CustomerStoreState" : "California",
"CustomerStoreCity" : "Los Angeles",
"Employee" : "Harv Mudd"
}, {
"ID" : 4,
"OrderNumber" : 35711,
"OrderDate" : "2014-01-12",
"SaleAmount" : 16050,
"Terms" : "15 Days",
"TotalAmount" : 16550,
"CustomerStoreState" : "California",
"CustomerStoreCity" : "San Jose",
"Employee" : "Jim Packard"
}....
]
For custom summaries you can use this
summary: {
totalItems: [{
name: "SelectedRowsSummary",
showInColumn: "SaleAmount",
displayFormat: "Sum: {0}",
valueFormat: "currency",
summaryType: "custom"
}
],
calculateCustomSummary: function (options) {
if (options.name === "SelectedRowsSummary") {
if (options.summaryProcess === "start") {
options.totalValue = 0;
}
if (options.summaryProcess === "calculate") {
if (options.component.isRowSelected(options.value.ID)) {
options.totalValue = options.totalValue + options.value.SaleAmount;
}
}
}
}
}
In the section if (options.summaryProcess === "calculate") { you can put your custom calc logic, in this case your total count.

Create an object with specified indexes

I am trying to use for loop for every object using jq.
Sample Input generated by Elasticsearch
{
"took": 202,
"timed_out": false,
"aggregations": {
"aggsDateHistogram": {
"buckets": [
{
"key": 1465974236000,
"search": {
"value": 14
}
},
{
"key": 1465975137000,
"search": {
"value": 16
}
}
]
}
}
}
I want to have an object that has a key value and corresponding value of value index from search.
{ "date": .aggregations.aggsDateHistogram.buckets[].key, "value": .aggregations.aggsDateHistogram.buckets[].search.value }
This gives me an object but with cartesian product, but I only want to have values like
key[1] : search[1].value
key[2] : search[2].value
So you want to produce this output?
[
{
"key": 1465974236000,
"value": 14
},
{
"key": 1465975137000,
"value": 16
}
]
The following will do just that:
.aggregations[].buckets
| map({key: .key, value: .search.value})
And from a terminal:
jq '.aggregations[].buckets
| map({key: .key, value: .search.value})' input.json
Here is a slightly simpler solution
[ .aggregations[].buckets[] | {key, value:.search.value} ]

How to insert into mongoDB from HTML page

var productDB = new Meteor.Collection('products'); //Want to insert into this DB
var ProductParameters = nodeDB.find({"ACTIVE" : 1, "VARIENTS.ACCESS" : "PUBLIC"}, { "VARIENTS.NAME": 1, _id : 0 } ); //Taking Paramters from Another DB
Template.dpVar.events = {
'click .addProduct' : function (e) {
e.preventDefault();
ProductParameters.forEach(function(){ **//This is my Question.How to insert into productDB the key values as {ProductParameters: Val of ProductParameters}**
console.log(ProductParameters);
var pvariable = {
pvariable: tmpl.find("#ProductParameters").value
};
productDB.insert(pvariable);
});
}
};
Problem:
I have created form from the Parameters of nodeDB.
I want to store the data from this new form in a new DB productDB.
I want to run a loop where all the ProductParameters are read from nodeDB and their corresponding values inserted in form by user are pushed into ProductDB as new Entry.
EDIT:
NodeDB has Templates:
db.nodes.insert([
{
"GEOLOCATION": {
"GEO_CODE": [],
"ACTIVE_GEOLOCATION": false
},
"META": {
"CATEGORY": "levis",
"DESCRIPTION": "dsad",
"PRIVACY": "PUBLIC",
"TEMPLATE_NAME": "B",
"TEMPLATE_GROUP": "Product",
"KEYWORDS": [
"sda"
],
"CREATEDBY": "",
"SUBCATEGORY": "Blue",
"PRODUCT_TEMPLATE_TYPE": "Consumable",
"UOM": "",
"TEMPLATE_SUBGROUP": ""
},
"VARIENTS": [
{
"COMMENT": "Demo",
"INDEX": 0,
"NAME": "Brand",
"IS_PARENT": false,
"DATATYPE": "Text",
"ACCESS": "PUBLIC",
"PARENT_VARIENT": "Parem",
"TYPE": "PERMANENT"
}
]
}
])
The form is generated only from the VARIENTS
The ProductDB would be {key,value} ={VARIENTS.NAME,value from UI}
There can be multiple VARIENTS as this contains only one "Brand"
instead of
var ProductParameters = nodeDB.find({"ACTIVE" : 1, "VARIENTS.ACCESS" : "PUBLIC"}, { "VARIENTS.NAME": 1, _id : 0 } );
add .fetch() at the end
var ProductParameters = nodeDB.find({"ACTIVE" : 1, "VARIENTS.ACCESS" : "PUBLIC"}, { "VARIENTS.NAME": 1, _id : 0 } ).fetch();

Resources