let's say I have this array:
array = [1,2,3,4,5,6,7,8,9,10];
Then I want to divide this array for each 2 batch with 5 array value:
a[0] = [1,2,3,4,5];
a[1] = [6,7,8,9,10];
This is my code until now keep trying.It should insert to db when batch has been slice for each job for 100 array value.
BatchList = new Meteor.Collection('batch_list');
var arrayAssetList = Asset.find({}, { _id: 1});
var data = [];
arrayAssetList.forEach(function(key){
data.push(key._id)
});
var arraySize = arrayAssetList.count() / 100;
var slice, sliceTo;
for(var i=0; i<arraySize; i++){
if(i == 0){
slice = 0
} {
slice = 100*i
}
if(i>1){
sliceTo = 100*i;
}
BatchList.insert({ data: data.slice(slice,sliceTo)});
}
it should be like this:
[{
_id: '()#()##)#*()#*#',
size: 100,
data: [1,2,3,4,100]
},{
_id: 'sdfsdfnnn3',
size: 100,
data: [100,101,102,103,200]
}]
Related
I have a list object that will collect the data and add it into a list of a list object, but every time the list object adds all data in a single list of data. Here is my output:-
dataList = [a,b,c,d]
pointDataList =[[a,b,c,d]]
dataList = [a,b,c,d,e,f]
pointDataList = [[a,b,c,d,e,f]]
I want this:-
dataList = [a,b,c,d]
pointDataList =[[a,b,c,d]]
dataList = [e,f]
pointDataList = [[a,b,c,d],[e,f]]
Here is my code:-
uploadData = [[{date: 2021-01-06, count: 3}, {date: 2021-02-08, count: 2}, {date: 2021-02-26,
count: 2}, {date: 2021-03-08, count: 1}], [{date: 2021-01-06, count: 1}, {date: 2021-02-26, count:
3}, {date: 2021-03-03, count: 6}], [{date: 2021-01-30, count: 2}], [{date: 2021-03-06, count: 1}],
[{date: 2021-01-30, count: 4}], [{date: 2021-03-06, count: 4}], [{date: 2021-03-01, count: 1}]];
for (int j = 0; j < uploadData.length; j++) {
graphData = uploadData[j];
barColor = colorList[j];
extension = extensionList[j];
print(
"Graph Data List >>>>>>> " +
graphData.toList().toString());
print("Graph Data Length::::::::>>>>> " + graphData.length.toString());
for (int l = 0; l < graphData.length; l++) {
datas.add(SalesData(graphData[l]["date"].toString(),
graphData[l]["count"].toInt(), barColor, extension));
}
print("Data List:>>>>>>>>>>>> " + datas.toList().toString());
datas.sort((a, b) => a.date.compareTo(b.date));
pointData.add(datas);
print(
"Point Data:::::::>>>>>>>>>>>>>>> " +
pointData.toString());
}
Thanks in advance.
I found it where goes wrong. Here's the answer:-
uploadData.toList().toString());
for (int j = 0; j < uploadData.length; j++) {
graphData = uploadData[j];
barColor = colorList[j];
extension = extensionList[j];
List<SalesData> datas = [];
for (int l = 0; l < graphData.length; l++) {
datas.add(SalesData(graphData[l]["date"].toString(),
graphData[l]["count"].toInt(), barColor, extension));
}
pointData.add(datas);
}
need to just place the List of object parameter inside the for loop. i.e. List datas = [];
Suppose I have a list of IDs I want to filter a Collection by:
const ids = [1, 2, 3, 4];
How do I filter the collection to match just those IDs? Something like this doesn't work:
return Coll.fetch({_id: {$all: ids}});
This will work:
return Collection.find({_id: {$in: ids}}).fetch();
Here's how I might approach this:
function hasAllIds(collections, ids) {
for (let i = 0; i < collections.length; i++) {
let count = collections[i].find({
_id: {
$in: ids
}
}).count();
if (count === ids.length) {
return collections[i];
}
}
return null;
}
const colls = [Meteor.users, Games]; //etc.
const ids = [1, 2, 3];
const coll = hasAllIds(colls, ids);
if (coll) {
coll.find(); //or whatever
}
I have some objects:
var array = [];
var obj1 = new Object();
obj1.category = 0;
obj1.sequence = 0;
obj1.otherAttr = 1;
array.push(obj1)
var obj2 = new Object();
obj2.category = 1;
obj2.sequence = 2;
obj1.otherAttr = 2;
array.push(obj2)
var obj3 = new Object();
obj3.category = 4;
obj4.sequence = 3;
obj1.otherAttr = 3;
array.push(obj3)
...
and I have collection in MongoDB:
{
category:0,
sequence:0,
anotherAttr:1
},
{
category:0,
sequence:1,
anotherAttr:2
},
{
category:0,
sequence:2,
anotherAttr:3
},
{
category:1,
sequence:0,
anotherAttr:4
},
{
category:1,
sequence:1,
anotherAttr:5
},
{
category:1,
sequence:2,
anotherAttr:6
},
...
I wanna insert these objects. But Before insert these, I want check overlapping category and sequence between these and document in MongoDB unrelated to otherAttr or anotherAttr. For example, I have objects like top, the result I need is :
{
category:0,
sequence:0,
anotherAttr:1
},
{
category:1,
sequence:1,
anotherAttr:5
}
I tried to $match. But can't check some conditions in many attributes.
If I want to query users' age > 18,
and export result to corresponding collection,
How could I do it by rewriteing the following script?
The following is psuedo code
source_collections = ["user_1", "user_2", ..., "user_999"]
output_collections = ["result_1", "result_2", ..., "result_999"]
pipeline = [
{
"$match":{"age": > 18}
}
{ "$out" : output_collections }
]
cur = db[source_collections].runCommand('aggregate',
{pipeline: pipeline,allowDiskUse: true})
The script you're looking for is something like:
var prefix_source = 'user_';
var prefix_output = 'result_';
var source_collections = [];
var output_collections = [];
var numCollections = 999;
for (var i = 1; i <= numCollections; i++) {
source_collections.push(prefix_source + i);
output_collections.push(prefix_output + i);
}
var pipeline = [{'$match': {age: {'$gt': 18}}}, {'$out': ''}]; for (var currentCollection = 0; currentCollection < source_collections.length; currentCollection++) {
pipeline[pipeline.length - 1]['$out'] = output_collections[currentCollection];
var cur = db[source_collections[currentCollection]].runCommand('aggregate', {pipeline: pipeline,allowDiskUse: true});
}
And while you're at it, the var cur = ... line could be simplified to
db[source_collections[currentCollection]].aggregate(pipeline, {allowDiskUse: true});
Note: I've added a piece that generates your arrays for you, as I'm sure you're not looking to write them by hand :D
I have a collection users in Mongo and I execute this map reduce which I believe is the equivalent of a COUNT(*) GROUP BY origin:
> m = function() { for (i in this.membership) {
... emit( this.membership[i].platform_profile.origin, 1 );
... } }
function () {
for (i in this.membership) {
emit(this.membership[i].platform_profile.origin, 1);
}
}
> r = function( id, values ) { var result = 0;
... for ( var i = 0; i < values.length; i ++ ) { result += values[i]; }
... return result; }
function (id, values) {
var result = 0;
for (var i = 0; i < values.length; i++) {
result += values[i];
}
return result;
}
> db.users.mapReduce(m, r, {out : { inline: 1}});
{
"results" : [
{
"_id" : 0,
"value" : 15
},
{
"_id" : 1,
"value" : 449
},
...
}
But if I try to count how many documents have this field set to a specific value like 1, I get fewer results:
db.users.count({"membership.platform_profile.origin": 1});
424
What am I missing?
Are your count queries using a sparse index by any chance? My only guess there would be if some other query criteria resulted in documents absent from from index to be ignored from the count.
I recreated your schema with some fixture data and the results between map/reduce and simple count queries are in agreement:
db.users.drop();
var map = function() {
for (i in this.membership) {
emit(this.membership[i].platform_profile.origin, 1);
}
};
var reduce = function(id, values ) {
var result = 0;
for (var i = 0; i < values.length; i++) {
result += values[i];
}
return result;
}
var origins = {1: "a", 2: "b", 3: "c", 4: "d"};
for (var i = 0; i < 1000; ++i) {
var membership = [];
for (var o in origins) {
if (0 == i % o) {
membership.push({ platform_profile: { origin: origins[o] }});
}
}
db.users.save({ membership: membership });
}
db.users.mapReduce(map, reduce, {out: {inline: 1}}).results.forEach(function(result){
print(result["_id"] + ": " + result["value"]);
});
for (var o in origins) {
print(origins[o] + ": " + db.users.count({"membership.platform_profile.origin": origins[o]}));
}
Here's the output:
$ mongo --quiet mr_count.js
a: 1000
b: 500
c: 334
d: 250
a: 1000
b: 500
c: 334
d: 250
You can use the following map/reduce for the equivalent of COUNT(*) GROUP BY origin
Map/Reduce Functions :
map = function() {
if(!this.membership) return;
for (i in this.membership) {
if(!this.membership[i].platform_profile || !this.membership[i].platform_profile.origin) return;
emit(this.membership[i].platform_profile.origin, 1);
}
}
reduce = function(key, values) {
var count = 0;
for (v in values) {
count += values[v];
}
return count;
}
result = db.runCommand({
"mapreduce" : "users",
"map" : map,
"reduce" : reduce,
"out" : "users_count"
});
I had the same issue. I replaced x.length by Array.sum(x) in the reduce function (assuming you emit 1 in the map function) and it works. I agree x.length should work too, but I cannot explain why it does not.