Using find() to match multiple conditions - meteor

I have been using this code to find whether a school exists in a collection or not
var sn = 'mit';
var schoolexists = Schools.find({schoolname: sn}, {limit: 1}).count() > 0;
if(schoolexists == true){
alert('school already exists');
}
This works but i now need to introduce two more pointed conditions like schoollocation,studentid and get only the records that satisfy those three conditions. How would i introduce the two extra conditions?.

Just add them to the selector (the first argument):
var selector = {
schoolName: 'mit',
shoolLocation: 'cambridge',
studentId: 'abc123'
}
var schoolexists = Schools.find(selector, {limit: 1}).count() > 0;
Selector fields are ANDed together.

Related

Laravel collection condition in sum

I have a collection of transactions with relations and I would like to sum column separated by condition of relation column. Right now I have this:
$delegatedProvision = 0;
$ownProvision = 0;
foreach ($transactions as $transaction) {
if ($transaction->discount->consider_improvement) {
$delegatedProvision += $transaction->stats->$column;
continue;
}
$ownProvision += $transaction->stats->$column;
}
$this->salesCollection->put('delegatedProvision', $delegatedProvision);
$this->salesCollection->put('ownProvision', $ownProvision);
It works but I would like to use Laravel collections. So far I have just this:
$provision = $transactions->sum(function ($transaction) use ($column) {
return $transaction->stats->$column;
});
And I don't know how to use condition in sum() method and according column $transaction->discount->consider_improvement (which is boolean) have sum in separated variables. I can use filter each for different consider_improvement but it means that I have to iterate all transactions twice.
Try this:
$collection->where(/* your condition */)->sum($column);

How to add new item in specific index?

I new in kotlin , i want to update an item in lists.
I use this code:
var index: Int
for (record in recordList)
if (record.id == updatedHeader?.id) {
index = recordList.indexOf(record)
recordList.add(index, updatedHeader)
}
but it cant do this, because of ConcurrentModificationException
Assuming that recordList is a MutableList and val (so, you'd like to modify the records in place), you can use forEachIndexed to find the records you care about and replace them.
This did not cause a ConcurrentModificationException:
recordList.forEachIndexed { index, record ->
if(record.id == updatedHeader?.id) recordList[index] = updatedHeader
}
On the other hand, if you redefine recordList as a non-mutable list, and a var, you could rewrite the entire list using map:
recordList = recordList.map { if(it.id == updatedHeader?.id) updatedHeader else it }
Of course, you could call .toMutableList() on the end of that if you wanted to turn your List into a MutableList.
If there's a single record with the given id in the list, you can find its index and add the header at that index:
val index = recordList.indexOfFirst { it.id == updatedHeader.id }
if (index >= 0)
recordList.add(index, updatedHeader)
If there are multiple records with the given id and you want to prepend header before each of them, you can use get listIterator and use its methods to modify the list during the iteration without getting ConcurrentModificationException:
val iterator = recordList.listIterator()
for (record in iterator) {
if (record.id == updatedHeader.id) {
iterator.previous() // move to the position before the record
iterator.add(updatedHeader) // prepend header
iterator.next() // move next, back to the record
}
}

Performance server scripting

I have table with multiple customerKey values assigned to a numeric value; I wrote a script where foreach row of data I scan whole table to find all values assigned to the current customerKey and return a highest one;
I have a problem with performance - script processes around 10 records per second - any ideas how to improve this or maybe propose an alternative solution plesae?
function getLastest() {
var date = app.models.magicMain.newQuery();
var date_all = date.run();
date_all.forEach(function(e) { // for every row of date_all
var temp = date_all.filter(function(x) {
return x.SubscriberKey === e.SubscriberKey; // find matching records for the current x.SubscriberKey
});
var dates = [];
temp.forEach(function(z) { // get all matching "dates"
dates.push(z.Date);
});
var finalValue = dates.reduce(function(a, b) { // get highest dates value (integer)
return Math.max(a, b);
});
var record = app.models.TempOperatoins.newRecord(); // save results to DB
record.email = e.SubscriberKey.toString() + " " + finalValue.toString();
app.saveRecords([record]);
});
}
The only suggestion I have would be to add:
var recordstosave = [];
At the top of your function.
Then replace app.saveRecords([record]) with recordstosave.push(record).
Finally outside of your foreach function do app.saveRecords(recordstosave).
I saw major processing time improvements doing this rather than saving each record individually inside a loop.

Firebase - How I can know first and last key

In my project, I must know first and last key of child to do something. I have query same below, I use 'i' to find first but I don't know how to get last key? Have any ways to set if Firebase query complete will do function with child_added? .In test, console.log(last) but is undefinded
var i = 0;
myDataRef.limitToLast(10).on('child_added', function (snapshot){
if( i == 0)
{
first = snapshot.key;
}
renderInfo(snapshot.key, snapshot.val(), 'new');
last = snapshot.key;
});
console.log(last)

Crossfilter reduce :: find number of uniques

I am trying to create a custom reduce function for a dataset attribute group that would sum a number of unique values for another attribute.
For example, my dataset looks like a list of actions on projects by team members:
{ project:"Website Hosting", teamMember:"Sam", action:"email" },
{ project:"Website Hosting", teamMember:"Sam", action:"phoneCall" },
{ project:"Budjet", teamMember:"Joe", action:"email" },
{ project:"Website Design", teamMember:"Joe", action:"design" },
{ project:"Budget", teamMember:"Sam", action:"email" }
So, team members work on a variable number of projects by performing one action per line. I have a dimension by team member, and would like to reduce it by the number of projects (uniques).
I tried the below (storing project in a uniques array) without success (sorry, this might hurt your eyes):
var teamMemberDimension = dataset.dimension(function(d) {
return d.teamMember;
});
var teamMemberDimensionGroup = teamMemberDimension.group().reduce(
// add
function(p,v) {
if( p.projects.indexOf(v.project) == -1 ) {
p.projects.push(v.project);
p.projectsCount += 1;
}
return p;
},
// remove
function(p,v) {
if( p.projects.indexOf(v.projects) != -1 ) {
p.projects.splice(p.projects.indexOf(v.projects), 1);
p.projectsCount -= 1;
}
return p;
},
// init
function(p,v) {
return { projects:[], projectsCount:0 }
}
);
Thanks a lot!
Edit after DJ Martin's answer ::
So, to be clearer, I would like to get the numbers I am after here would be:
-----------
Sam : 2 (projects he is workin on, no matter the number of actions)
Joe : 2 (projects he is workin on, no matter the number of actions)
-----------
The answer provided by DJ Martin gets me there. But rather than hard coding a table, I would like to find a way to use these numbers for my DC.JS bar chart. When I was only using the number of actions (so just a reduceCount() ), I did it like below:
teamMemberChart.width(270)
.height(220)
.margins({top: 5, left: 10, right: 10, bottom: 20})
.dimension(teamMemberDimension)
.group(teamMemberDimensionGroup)
.colors(d3.scale.category20())
.elasticX(true)
.xAxis().ticks(4);
I guess there might be something to change in the group().
UPDATED ANSWER
Sorry I misunderstood the question... you are actually on the right track. You'll just need to maintain a count of each project so that your subtract function can know when to remove the value.
teamMemberGroup = teamMemberDimension.group().reduce(
function (p, d) {
if( d.project in p.projects)
p.projects[d.project]++;
else p.projects[d.project] = 1;
return p;
},
function (p, d) {
p.projects[d.project]--;
if(p.projects[d.project] === 0)
delete p.projects[d.project];
return p;
},
function () {
return {projects: {}};
});
Here is an updated fiddle: http://jsfiddle.net/djmartin_umich/3LyhL/

Resources