i'm building an ag-Grid in Vue.js . I'm trying to set colDefs and dataRow dinamically, and all is ok but i've "actualComparator is not a function" error when i set a date filter.
coldefs are dinamics and i receive from json
colDefs:[
{
"field" : "field1",
"filter" : "text",
"headerName" : "Name",
"width" : 100},
{
"field" : "filed2",
"filter" : "text",
"headerName" : "Surname",
"width" : 80},
{
"field" : "date1",
"filter" : "agDateColumnFilter",
"filterParams" : {
"clearButton" : true,
"comparator" : "dateFilterComparator"
},
"headerName" : "Birth",
"width" : 150
}]
dateFieldComparator is a function inside the methods
dateFilterComparator(filterLocalDateAtMidnight, cellValue){
console.log("I'm here");
var dateAsString = cellValue;
if (dateAsString == null) return -1;
var dateParts = dateAsString.split("/");
var cellDate = new Date(Number(dateParts[2]), Number(dateParts[1]) - 1, Number(dateParts[0]));
if (filterLocalDateAtMidnight == cellDate) {
return 0;
}
else if (cellDate < filterLocalDateAtMidnight) {
return -1;
} else {
return 1;
}
}
The request for the json (dataRow + colDefs) is send on the beforeMount eventhook, ag-grid is showed correctly but when i try to set a filter on the date i receive the error above.
The Clear Filter button is showed but the comparator seems not initialized with my function dataParamComparator.
I've try to call the gridOptions.api.setColumnDefs() on the onReady but without success.
Regards
Davide
Related
I use MongoDB version 2.6.10. Below is the collection structure. I use MapReduce function to group the names of the user based on (created(excluding seconds), event_name.
{
"_id" : ObjectId("59c11d79078dc54153c36ee8"),
"event_name" : "notification",
"created" : ISODate("2017-09-19T13:36:57.252Z"),
"sender_name" : "nathan",
"user_name": "Ragul"",
}
{
"_id" : ObjectId("59c11d79078dc54153c36eeb"),
"event_name" : "notification",
"created" : ISODate("2017-09-19T13:36:57.772Z"),
"sender_name" : "parmesh",
"user_name": "Ram",
}
{
"_id" : ObjectId("59c11d7a078dc54153c36ef0"),
"event_name" : "notification",
"created" : ISODate("2017-09-19T13:36:58.554Z"),
"sender_name" : "nathan",
"user_name": "Ram",
}
{
"_id" : ObjectId("59c11d7a078dc54153c36ef1"),
"event_name" : "message",
"created" : ISODate("2017-09-19T13:36:58.577Z"),
"sender_name" : "nathan",
"user_name": "Ragul"",
}
Below is my query using MapReduce function. My question is whether we can use calculated date as a mapper. Help me with your suggestions
var mapfn = function(){
if (this.event_name == "message"){
name = this.recipient_name
}
else if ((this.event_name == "notification") && (this.other_status == true)){
name = this.sender_name
}
else if ((this.event_name == "notification") && (this.other_status == false)){
name = "You"
}
this.cre = {$subtract:[this.created,{$add:[{$multiply:[{$second:this.created},1000]},{$millisecond:this.created}]}]}
emit({"event_name": this.event_name, "created": this.cre}, name)
}
var redfun = function(key, value){
return Array.append(value)
}
db.getCollection('users').mapReduce(mapfn, redfun, {out: "example"}).find()
Here instead calculating the date using MongoDB expression, I tried to use javascript to eliminate the seconds and then I mapped then its worked.
var mapfn = function(){
if (this.event_name == "message"){
name = this.recipient_name
}
else if ((this.event_name == "notification") && (this.other_status == true)){
name = this.sender_name
}
else if ((this.event_name == "notification") && (this.other_status == false)){
name = "You"
}
this.created.setSeconds(0);
this.created.setMilliseconds(0);
emit({"event_name": this.event_name, "created": this.created}, name)
}
var redfun = function(key, value){
var names = value.join(",")
return names
}
db.users.mapReduce(mapfn, redfun, {out: "example"}).find()
How can I project one BsonDocument to new instance without querying a collection?
inputs: document: BsonDocument, fields: new string[] { "_id", "meta.name", "type" }
output: BsonDocument with only the above elements populated
Itch scratched
input
{
"_id" : ObjectId("58b454f40960a1788ef48ebc"),
"schema" : {
"id" : "asset",
"version" : {
"major" : 1,
"minor" : 0
}
},
"type" : "asset",
"meta" : {
"name" : "Most Amazing Product",
"type" : null,
"legacy" : {
"url" : "https://s3.amazonaws.com/bucket_name/guid"
}
},
"content" : {
"is_s3" : true,
"s3_bucket" : "bucket_name",
"s3_key" : "guid.doc",
"url" : "https://s3.amazonaws.com/guid.doc"
},
"modified-date" : ISODate("2017-08-09T15:25:57.972Z"),
"modified-by" : "api"
}
code
nuget: MongoDB.Driver 2.4.4
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.IO;
BsonDocument original = BsonDocument.Parse(#"{ ""_id"" : ObjectId(""58b454f40960a1788ef48ebc""), ""schema"" : { ""id"" : ""asset"", ""version"" : { ""major"" : 1, ""minor"" : 0 } }, ""type"" : ""asset"", ""meta"" : { ""name"" : ""Most Amazing Product"", ""type"" : null, ""legacy"" : { ""url"" : ""https://s3.amazonaws.com/bucket_name/guid"" } }, ""content"" : { ""is_s3"" : true, ""s3_bucket"" : ""bucket_name"", ""s3_key"" : ""guid.doc"", ""url"" : ""https://s3.amazonaws.com/guid.doc"" }, ""modified-date"" : ISODate(""2017-08-09T15:25:57.972Z""), ""modified-by"" : ""api"" }");
string[] fields = new[] { "_id", "meta.name", "type" };
BsonDocument projection = new BsonDocument();
foreach (var fieldName in fields)
{
BsonDocument source = original;
BsonDocument target = projection;
string[] parts = fieldName.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < parts.Length; i++)
{
string currentName = parts[i];
if (i == parts.Length - 1)
{
if(source.Contains(currentName))
target[currentName] = source[currentName];
}
else
{
// Does the source have a current property at this level
if (source.Contains(currentName))
{
// first time this has been visited on target
if (target.Contains(currentName) == false)
{
target.Add(currentName, new BsonDocument());
}
source = source[currentName] as BsonDocument;
target = target[currentName] as BsonDocument;
}
else
{
// no need to go any further if the source doesn't have the property specified
break;
}
}
}
}
result
{
"_id" : ObjectId("58b454f40960a1788ef48ebc"),
"meta" : {
"name" : "Most Amazing Product"
},
"type" : "asset"
}
I am trying to compare dates in '$where' query to filter data. My 'where' query looks something like this:
function () {
var messageStatusInfoList = this.messageStatusInfoList
var startDate = someDate;
var result = false;
for (var counter = 0; counter < messageStatusInfoList.length; counter++) {
var currentMessageStatusInfo = messageStatusInfoList[counter]
if (counter > 0 && (currentMessageStatusInfo.messageStatus == "RESPONDED" )) {
var responseDate = currentMessageStatusInfo.effectiveDate
if(+responseDate >= +startDate) {
result = true;
break;
}
}
}
return result;
}
Here is sample input document:
{
"_id" : NumberLong(3687),
"messageStatusInfoList" : [
{
"effectiveDate" : ISODate("2014-08-01T13:29:26.456Z"),
"expirationDate" : ISODate("2014-08-04T11:40:29.824Z"),
"messageStatus" : "OPENED"
},
{
"effectiveDate" : ISODate("2014-08-04T11:40:29.824Z"),
"expirationDate" : ISODate("2014-08-05T13:01:00.135Z"),
"messageStatus" : "RESPONDED",
"userId" : NumberLong(8)
},
{
"effectiveDate" : ISODate("2014-08-05T13:01:00.135Z"),
"messageStatus" : "REPLY_TO_CUSTOMER",
"userId" : NumberLong(8)
}
],
"tenantId" : NumberLong(4),
"text" : "some text ..",
"version" : NumberLong(12)
}
As per the above document and given where query, if startDate is set to 2014-08-03, then the date comparison should evaluate to true(because responseDate is 2014-08-04T11:40:29.824Z and responseDate is greater than startDate). But it is not happening so. The comparison operator evaluates to false.
The issue was due to improper initialization of variable startDate in my where query.
I had data structure in MongoDB as below
{
"_id" : ObjectId("523aab00045624a385e5f549"),
"name" : "English Book 29",
"SKU" : 1000549081,
"price" : 249000,
"image" : null,
"category_id" : ObjectId("523a7802b50418baf38b4575"),
"category_name" : "English Book",
"details" : {
"Title" : "Title 549081",
"Binding" : 1,
"Author" : "Author 0",
"Publication data" : 0.5263832447608386,
"Publisher name" : "Publisher name 14",
"Number of page" : 90
}
}
Binding of book has 2 values:
0 that means soft binding, and 1 that means hard binding. I write Map Reduce to statistics for each values.
var map = function()
{
for(var key in this.details)
{
if(key == 'Binding')
{
emit({name: key}, {
'data':
[
{
name: this.details[key],
count: 1
}
]
});
}
}
};
var reduce = function (key, values) {
var reduced = {};
for(var i in values)
{
var inter = values[i];
for(var j in inter.data)
{
if(typeof(reduced[inter.data[j].name]) != "undefined")
{
reduced[inter.data[j].name] += inter.data[j].count;
}
else
{
reduced[inter.data[j].name] = 1;
}
}
}
return reduced;
};
When I run with small data (50 records) result return exactly. But when I run it with real data (192000 records) result return Not exactly. The result as below
{
"_id" : {
"name" : "Binding"
},
"value" : {
"0" : 50,
"1" : 50
}
}
I checked return data when Map/Reduce done, result as below
"counts" : {
"input" : 192000,
"emit" : 192000,
"reduce" : 1920,
"output" : 1
},
What wrong with it. Welcome any suggestion, explanation.
Thanks and best regards,
After researching about Map/Reduce yesterday, I realized that, "Emit" send 100 elements once, and "Reduce" perform on this data set. So my above code is wrong because it only "SUM" on small data set.
Below that is my new code for Map-Reduce
var map = function ()
{
for(var key in this.details)
{
if(key == 'Binding')
{
var value = {};
value[this.details[key]] = 1;
emit(key, value);
}
}
}
var reduce = function (key, values)
{
var reduced = {};
for(var idx = 0; idx < values.length; idx++)
{
var inner = values[idx];
for (var j in inner)
{
if (typeof (reduced[j]) == 'undefined')
{
reduced[j] = 0;
}
reduced[j] += inner[j];
}
}
return reduced;
}
I post here for anyone who meet similar situation. Thanks for reading.
I have a below map:
var mapFunction = function() {
if(this.url.match(/http:\/\/test.com\/category\/.*?\/checkout/)) {
var key=this.em;
var value = {
url : 'checkout',
count : 1,
account_id:this.accId
}emit(key,value); };
if(this.url.match(/http:\/\/test.com\/landing/)) {
var key=this.em;
var value = {
url : 'landing',
count : 1,
account_id:this.accId
}emit(key,value); };
}
Then I have defined reduce something like below:
var reduceFunction = function (keys, values) {
var reducedValue = {count_checkout:0, count_landing:0};
for (var idx = 0; idx < values.length; idx++) {
if(values[idx].url=='checkout'){
reducedValue.count_checkout++;
}
else {
reducedValue.count_landing++;
}
}
return reducedValue;
}
Now, lets say I have only 1 record:
{
"_id" : ObjectId("516a7cff6dad5949ddf3f7b6"),
"ip" : "1.2.3.4",
"accId" : 123,
"em" : "testing#test.com",
"pgLdTs" : ISODate("2013-04-11T18:30:00Z"),
"url" : "http://test.com/category/prr/checkout",
"domain" : "www.test.com",
"pgUdTs" : ISODate("2013-04-14T09:55:11.682Z"),
"title" : "Test",
"ua" : "Mozilla",
"res" : "1024*768",
"rfr" : "www.google.com"
}
Now if I fire my map reduce like below:
db.test_views.mapReduce(mapFunction,reduceFunction,{out:{inline:1}})
The I get below result returned:
{
"_id" : "testing#test.com",
"value" : {
"url" : "checkout",
"count" : 1,
"account_id" : 123
}
}
So, its basically returning me the map. Now, if I go a add another document for this email id. Finally it becomes something like below.
{
"_id" : ObjectId("516a7cff6dad5949ddf3f7b6"),
"ip" : "1.2.3.4",
"accId" : 123,
"em" : "testing#test.com",
"pgLdTs" : ISODate("2013-04-11T18:30:00Z"),
"url" : "http://test.com/category/prr/checkout",
"domain" : "www.test.com",
"pgUdTs" : ISODate("2013-04-14T09:55:11.682Z"),
"title" : "Test",
"ua" : "Mozilla",
"res" : "1024*768",
"rfr" : "www.google.com"
}
{
"_id" : ObjectId("516a7e1b6dad5949ddf3f7b7"),
"ip" : "1.2.3.4",
"accId" : 123,
"em" : "testing#test.com",
"pgLdTs" : ISODate("2013-04-11T18:30:00Z"),
"url" : "http://test.com/category/prr/checkout",
"domain" : "www.test.com",
"pgUdTs" : ISODate("2013-04-14T09:59:55.326Z"),
"title" : "Test",
"ua" : "Mozilla",
"res" : "1024*768",
"rfr" : "www.google.com"
}
Then, I go again and fire the map reduce, it gives me proper results
{
"_id" : "testing#test.com",
"value" : {
"count_checkout" : 2,
"count_landing" : 0
}
}
Can anyone please help me out in understanding why it returns me a map for single document and doesn't do the counting in reduce.
Thanks for help.
-Lalit
Can anyone please help me out in understanding why it returns me a map for single document and doesn't do the counting in reduce.
The Reduce step combines documents with the same key into a single result document. If you only have one key in the data emitted by your Map function, the data is already "reduced" and the reduce() will not be called.
This is the expected behaviour of the MapReduce algorithm.
The reduce function should return the same type of value objects as the map function emits.
Like you've experienced, when there's a single value associated with a key - the reduce function will not be called at all .
From the MongoDB MapReduce Documentation:
Requirements for the reduce Function:
...
the type of the return object must be identical to the type of the value emitted by the map function to ensure that the following operations is true:
reduce(key, [ C, reduce(key, [ A, B ]) ] ) == reduce( key, [ C, A, B ] )