Acessing inner element of json array from mapreduce - arrays

My sample Json object is as follows
{
"numRecommenders": 0,
"publicProfileUrl": "http://www.linkedin.com/pub/heena-vyas/16/786/826",
"positions": {
"total": 1,
"positionList": [
{
"id": "91286566",
"title": "senior executive",
"company": {
"name": "Reliance",
"industry": "Oil & Energy",
"type": "Public Company",
"size": "10,001+ employees"
},
"isCurrent": true
}
]
},
My mapreduce function is give below:
String map = "function() {"
+"for (index in this.positions.positionList) {"
+"emit(this.positions.positionList[index].company.name, {count: 1});"
+"}}";
String reduce = "function(key, values) {" + "var sum = 0;"
+ "values.forEach(function(value) {" + "sum += value['count'];"
+ "});" + "return {count: sum};" + "};";
MapReduceCommand mapReduceCommand = new MapReduceCommand(
mongoCollection, map, reduce.toString(), null,
MapReduceCommand.OutputType.INLINE, null);
MapReduceOutput out = mongoCollection.mapReduce(mapReduceCommand);
But current I'm working with 1.5 million objects from mongoDb.
I'm getting the following exception..
Exception in thread "main" com.mongodb.CommandResult$CommandFailure: command failed [command failed [mapreduce] { "assertion" : "too much data for in memory map/reduce" , "assertionCode" : 13604 , "errmsg" : "db assertion failure" , "ok" : 0.0}
at com.mongodb.CommandResult.getException(CommandResult.java:70)
at com.mongodb.CommandResult.throwOnError(CommandResult.java:116)
at com.mongodb.DBCollection.mapReduce(DBCollection.java:961)
at com.mongo.dboperations.MongoStorage.runGroupCommand(MongoStorage.java:126)
at com.mongo.dboperations.MongoStorage.main(MongoStorage.java:218)
How to resolve this exception?

Inline output for map/reduce in MongoDB is the fastest option, provided that your output fits within the 16 MB limit. Beyond that, you have to output to a collection.

Related

Typescript filter array of object by another array of strings

i stuck at my typescript filter function.
I have an array of objects:
[
{
"id": 12345,
"title": "Some title",
"complexity": [
{
"slug": "1" // my search term
"name": "easy"
}, {
"slug": "2" // my search term
"name": "middle"
},
{...}
And i have a array of strings with the allowed complexity:
public allowedComplexityArray:Array<string> = ["1"];
My Task: I only want to show objects with the allowed complexity of "1".
But somehow my function dont work and i dont know why:
allowedMeals = meals.filter(meal => {
return meal.complexity.every(complexityObj => that.allowedComplexityArray.indexOf(complexityObj.slug) > -1)
});
try:
let allowedMeals = data.filter(meal => {
return meal.complexity.findIndex(complexityObj =>
allowedComplexityArray.findIndex(m => m == complexityObj.slug) > -1) > -1
});
I'm using findIndex instead of filter in the return clause so it does not need to scan the whole array every time.

in array, json data and put in MySql with php

I have a data under format 'JSON' like this one :
{
"email": "john#john.fr",
"line_items": [
{
"sku": "123456789",
"price": "0.67",
"price_with_tax": "4.00",
"tax_lines": [
{
"title": "tax010",
"rate": 0.01,
"price": "1.11"
},
{
"title": "tax00200",
"rate": 0.02,
"price": "2.22"
}
]
},
{
"sku": "012345666",
"price": "1.67",
"price_with_tax": "5.00",
"tax_lines": [
{
"title": "tax0003000",
"rate": 0.03,
"price": "3.33"
}
]
}
]
}
I want put it in my database (MySql) by PDO::prepare. My following sql query works but second line_items have not good value im Mysql :
1st item :::: good value
email:john#john.fr
sku:123456789
price:0.67
price_with_tax:4.00
price_tax1:1.11
price_tax2:2.22
2nd item ::::
email:john#john.fr
sku:012345666
price:1.67
price_with_tax:5.00
wrong value ::::
price_tax1:1.11
price_tax2:2.22
How can I put it good value ?
here is my code :
$dataDecode = json_decode($jsondata);
$email = $dataDecode->email;
try
{
$dtbs = new PDO($dsn_dev, $pdo_user, $pdo_password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
}
catch (Exception $e)
{
die('Error : ' . $e->getMessage());
}
try
{
foreach ($dataDecode->line_items as $obj)
{
$var_sku = $obj->sku;
$var_price = $obj->price;
$var_price_with_tax = $obj->price_with_tax;
$taxNewArray = array();
foreach ($dataDecode->line_items[0]->tax_lines as $obj2)
{
array_push($taxNewArray , $obj2);
}
$val1st = array_shift($taxNewArray);
$val2nd = array_pop ($taxNewArray);
$var_tax1 = $val1st->price;
$var_tax2 = $val2nd->price;
$stmt = $dtbs->prepare("INSERT INTO $tabledata ($mysql_email, $mysql_sku, $mysq_price, $mysql_price_with_tax, $mysql_price__tax1___line_items, $mysql_price__tax2___line_items)
VALUES (:email, :sku, :price, :price_with_tax, :price_tax1, :price_tax2)");
$stmt->execute(array(':email'=>$email,
':sku'=>$var_sku,
':price'=>$var_price,
':price_with_tax'=>$var_price_with_tax,
':price_tax1'=>$var_tax1,
':price_tax2'=>$var_tax2
));
}
}
catch(Exception $e)
{
throw $e;
}
Do you have a idée ?
If there's only one entry in tax_lines, your code will try to set $var_tax2 from the nonexistent second entry. You need to check for this and substitute some other value:
$var_tax2 = $val2nd ? $val2nd->price : '0.0';
The other problem is this line:
foreach ($dataDecode->line_items[0]->tax_lines as $obj2)
You're using the tax lines from the first line item every time. That should be:
foreach ($obj->tax_lines as $obj2)

How to Stringify a sObject

I have a list of sObjects and I'd like to convert all the sObject fields to a string. For instance (this is the print out from a SOQL query),
Custom_sobj__c{
"serId": 5,
"value": {
"Id": "a0FJ0000005zIbwMAE",
"Contact__r": {
"serId": 6,
"value": {
"Name": "Bob Bobenson",
"Owner": {
"serRefId": 4
},
"Rule_Class__c": "Class III - Quote\/De (2 more) ...",
"OwnerId": "005d000000450RiAAI",
"Id": "003J0000016ZjuCIAS"
}
},
"Contact__c": "003J0000016ZjuCIAS"
}
}
And I have a list of these objects. I'd like to convert it all to string, so it looks something like this:
...'sobjInstance3{"serid";5,"value":...}','sobjInstance4{"serid";5,"value":...}',...
I have a for loop iterate through the list,
String strSobjects = ' ';
for(Custom_sobj__c obj : sobjList){
strSobjects = strSobjects + ','+String.valueOf(obj);
}
but this only returns the "ID" and "Contact__c". The string is getting the "Name" or "Rule_Class_c" fields.
How can I grab the rest of the data?
The System.JSON method should do the trick: https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_json_overview.htm
Something like:
String strSobjects = ' ';
for(Custom_sobj__c obj : sobjList){
strSobjects = strSobjects + ','+JSON.Serialize(obj);
}

Return an array from an Ember computed property

I have two related models - Task and Requirement. Requirements can be one of 3 types (Part, Tool, Material). A Task can have several requirements including several of the same type.
Task A
Requirement 1 (Part)
Requirement 2 (Part)
Requirement 3 (Tool)
Requirement 4 (Material)
Requirement 5 (Tool)
When viewing a single Task I want to group the list of requirements by type in a sort of summary view.
Task A
Parts Requirements (2)
Tooling Requirements (2)
Materials Requirements (1)
I have a computedProperty mostly functioning in my TaskController but I can't seem to get it to return back the array of requirement summaries that I'm building. All the fixture data is setup properly for both models (I can iterate each requirement and show it in the template with no issues).
Here are the models
Task model
App.Task = DS.Model.extend({
name: DS.attr()
requirements: DS.hasMany('requirement', { async: true})
});
Requirement model
App.Requirement = DS.Model.extend({
task_id: DS.belongsTo('task'),
type: DS.attr(),
description: DS.attr(),
quantity: DS.attr()
})
Here is the controller:
App.TaskController
App.TaskController = Em.ObjectController.extend({
requirementSummary: function () {
var self = this,
results = [];
self.get('requirements').then(function(requirements) {
var arrRequirements = requirements.get('content');
var parts = {
name: 'Parts',
description: '',
count: 0,
css_class: 'fa-cog'
},
tools = {
name: 'Tools',
description: '',
count: 0,
css_class: 'fa-wrench'
},
materials = {
name: 'Materials',
description: '',
count: 0,
css_class: 'fa-tint'
};
arrRequirements.forEach(function (requirement) {
if (requirement._data.name == 'Part') {
parts.description += requirement._data.description + ' (' + requirement._data.quantity + ')<br>';
parts.count++;
} else if (requirement._data.name == 'Material') {
materials.description += requirement._data.description + ' (' + requirement._data.quantity + ')<br>';
materials.count++;
} else if (requirement._data.name == 'Tooling') {
tools.description += requirement._data.description + ' (' + requirement._data.quantity + ')<br>';
tools.count++;
}
});
if (parts.description !== '') {
parts.description = parts.description.replace(/(<br>\s*)+$/);
} else {
parts.description = "No Parts requirements found";
}
if (materials.description !== '') {
materials.description = materials.description.replace(/(<br>\s*)+$/);
} else {
materials.description = "No Materials requirements found";
}
if (tools.description !== '') {
tools.description = tools.description.replace(/(<br>\s*)+$/);
} else {
tools.description = "No Tooling requirements found";
}
results.pushObject(parts);
results.pushObject(tools);
results.pushObject(materials);
});
return results;
}.property()
});
Currently it returns back the empty results array because it is waiting on the self.get promise to fulfill. If I return the result of self.get('requirements').then(...) then it returns the promise, not the results array and Ember isn't happy because it's not an array. What I want is for it to return back the populated results array.
The closest question I've found is here but it either doesn't solve the issue or I'm missing something.
You'll need to be using requirementSummary using an observable pattern, or after it's finished resolving.
Additionally this is not required due to requirements already being an iterable field:
var arrRequirements = requirements.get('content');
And you should be using a getter to get a property, not going to ._data.property
requirement.get('description')
Add this to your task template and you should see it populate (asynchronously):
{{#each requirement in requirementSummary}}
Name: {{requirement.name}} - Total: {{requirement.total}}
{{/each}}
The routes all seem to be working as well as the fixtures - I can use {{#each requirement in requirements}} and list each individual requirement with no issues. Just having the problem of generating the summarized property and accessing it after it's computed.
from routes/application_routes.js
this.resource( 'tasks', function () {
this.resource( 'task', { path: ':task_id' }, function () {
this.resource( 'task_requirements', { path: 'requirements' } );
} );
} );
from routes/task_routes.js
// List Tasks
App.TasksRoute = Em.Route.extend({
model: function () {
return this.store.find('task');
}
});
// Task Detail Route
App.TaskRoute = Em.Route.extend({
model: function(params) {
return this.store.find('task', params.task_id);
}
});
// Task Requirements Route
App.TaskRequirementsRoute = Em.Route.extend({
beforeModel: function () {
this.set('task', this.modelFor('task'));
}
});
Fixtures
// SAMPLE TASK FIXTURE.
App.Task.FIXTURES = [
{
"id": 1,
"name": "Test Task #1",
"description": "This is a test task. There are many like it but this one is mine.",
"requirements": [ 1, 2, 3, 4 ]
}
];
// SAMPLE REQUIREMENT FIXTURE
App.Requirement.FIXTURES = [
{
"id": 1,
"task_id": 1,
"type": "Part",
"description": "This is a Part requirement",
"quantity": 4
},
{
"id": 2,
"task_id": 1,
"type": "Part",
"description": "This is a Part requirement",
"quantity": 1
},
{
"id": 3,
"task_id": 1,
"type": "Material",
"description": "This is a Material requirement",
"quantity": 3
},
{
"id": 4,
"task_id": 1,
"type": "Tool",
"description": "This is a Tooling requirement",
"quantity": 1
}
];

How do I search for a string in a MongoDB document array and project the array value in a find operation?

I have created and inserted some simple json documents, each with an array into mongo:
MongoDB shell version: 2.4.6
use test
> db.sandbox.insert({ "array1" : [ "praxis a", "value b", "theory c"] })
> db.sandbox.insert({ "array1" : [ "mean d", "minimum e"] })
> db.sandbox.insert({ "array1" : [ "maximum f"] })
Then I searched for documents in the collection that contained an array1 value starting with the string 'field1'
> db.sandbox.find({"array1" : /praxis/})
This returned a single document, as expected:
{ "_id" : ObjectId("52585223b8a783860470f07b"), "array1" : [ "praxis a", "value b", "theory c" ] }
However, what I really wanted was to only return the array1 field value that matched. So I tried to project the first matching item from the array:
> db.sandbox.find({"array1" : /praxis/}, {_id: 1, "array1.$": 1})
When I tried this, I got a strange error:
error: {
"$err" : "positional operator (array1.$) requires corresponding field in
query specifier",
"code" : 16352
}
What I was hoping to get back was the value:
"field1: a"
What I thought I was settling for was to get back the array:
{ "array1: [ "praxis a", "value b", "theory c"] }
I would appreciate some help with the find function and how to project the value from the array using $ match...
This sure looks like a bug, and is similar to SERVER-9028.
There does seem to be a couple work-arounds, as both of these work:
db.sandbox.find({array1: 'praxis a'}, {'array1.$': 1})
OR
db.sandbox.find({array1: {$in: [/praxis a/]}}, {'array1.$': 1})
Both of these produce output of:
{
"_id": ObjectId("5258620315b3beb195f855b8"),
"array1": [
"praxis a"
]
}

Resources