thorus
April 25, 2019, 9:52am
1
I get this error:
TypeError: Events.aggregate is not a function
at VueComponent.getyears (frontpage.vue:777)
html (vue,Vuetify)
<v-select
v-model="selected"
:items="getyears"
hide-details
label="Select"
single-line
></v-select>
script
export default {
meteor: {
getyears() { return Events.aggregate(
{ $match: { category: 'running' } },
{ $group : {
_id: {
year : { $substr : ["$thedate", 0, 4 ] }
},
count: { $sum: 1 }
}
},
{ $sort : { _id : -1}}
);
}
},
I’m new to aggregation in Meteor, so how to use it correct?
The mongodb aggregate works when I test in ROBO 3T
1 Like
Aggregation is only available on the server and only using rawCollection
. You have a couple of options:
Do the aggregation in a Meteor Method, which you Meteor.call
from your Vue component (on-demand). The method would look something like:
Meteor.methods({
async doMyAggregation() {
return await Events.rawCollection().aggregate(
{ $match: { category: 'running' } },
{
$group: {
_id: {
year: { $substr: ["$thedate", 0, 4] }
},
count: { $sum: 1 }
}
},
{ $sort: { _id: -1 } }
).toArray();
}
});
Use something like tunguska:reactive-aggregate
if you want to subscribe reactively to an aggregation.
7 Likes
thorus
April 25, 2019, 11:44am
3
Is there a better and easier way to count years in my collection?
I just need like:
2019: 19 events
2018: 15 events
2017: 10 events
e.g…
It depends
“Better” and “easier” are probably very subjective. I’ll start with some questions:
How many documents are in your collection?
How many category: 'running'
documents are in your collection?
Is category
an index?
Does the client see a subset of those documents?
If so, how many does it see?
That indicates you will probably be able to do the counting in code on the client itself. You should ensure you are working from an array, so make sure to fetch()
your collection’s find()
. Then, generate a new array of years and then count matching years into a new array. Something like this might work:
function getyears() {
return Events.find({ category: 'running' })
.fetch()
.map(doc => doc.thedate.substr(0, 4))
.reduce((years, year) => {
if (year in years) {
years[year]++;
} else {
years[year] = 1;
}
return years;
}, {});
}
3 Likes
I think you misunderstood what I was asking. If you’re doing a find({category:'running'})
you should ensure the category
field in your Events collection is indexed, or you’ll get potentially crippling performance issues - especially with 100000+ documents. That will also affect any publications you may do like that.
thorus
April 26, 2019, 8:39am
8
Perfekt, but now I have trouble with getting the data names from the getyears function:
I’m trying to get at v-select to work with some data, but I only get object,object https://codepen.io/nordthorus/pen/zXyewY (the getyears works, its just the v-selcted that dont)
I can se the data with: Selected: {{ selected }} when i click the only dropdown with object,object (it like I need to use a v-for with options)
Selected: { “2018”: 1, “2019”: 1 }
I haven’t used Vue and don’t really understand what may be happening, so I can’t offer any immediate help. Perhaps the result from getyears
is not in the right format for Vue?
thorus
April 26, 2019, 9:01am
10
It worked with:
<select v-model="selected">
<option v-for='(value, key) in getyears' :value='key' >{{key}} - {{value}} gang(e)</option>
</select>
1 Like
thorus
April 29, 2019, 8:36am
11
robfallows:
function getyears
Hi again,
Howto sendt a (categoryId variable to function getyears?
category: ‘running’ -> running have to be the categoryId from the list i’m looping.
Birthday: id: 1
Running: id: 2
Mtb: id:3
I don’t understand what you’re asking.
thorus
April 29, 2019, 12:05pm
13
Sorry, I will try again
Have to find Events where category is the same as a variable that comes from: (VARIABLE = thecat.name)
<v-card v-if="catId == thecat.name" v-for="thecat in getcats" :key="thecat._id">
<span class="grey-light pt-3 mt-3">
<select v-model="thisYear">
<option v-for='(value, key) in getyears' :value='key'>{{key}} - {{value}} gang(e)</option>
</select>
</span>
</v-card>
So howto send a VARIABLE to: Mtb = VARIABLE = thecat.name
export default {
meteor: {
getyears: () {
return Events.find({ category: VARIABLE })
.fetch()
.map(doc => doc.thedate.substr(0, 4))
.reduce((years, year) => {
if (year in years) {
years[year]++;
} else {
years[year] = 1;
}
return years;
}, {});
}
Unless I still don’t understand:
<option v-for='(value, key) in getyears(thecat)' :value='key'>{{key}} - {{value}} gang(e)</option>
and
export default {
meteor: {
getyears(category) {
return Events.find({ category })
.fetch()
.map(doc => doc.thedate.substr(0, 4))
.reduce((years, year) => {
if (year in years) {
years[year]++;
} else {
years[year] = 1;
}
return years;
}, {});
}
2 Likes
thorus
April 29, 2019, 12:13pm
15
robfallows:
(thecat)
I get this: [Vue warn]: Error in render: “TypeError: _vm.getyears is not a function”
thorus
April 29, 2019, 12:16pm
16
Is it becasue I use in:
export default {
meteor: {
so it can not take variables?
Normally I can do waht you wtrite but not in
export default {
meteor: {
Well, as I said earlier, I haven’t used Vue. So, using my approach of “I don’t know what I’m doing, so try this”, you could try this:
<option v-for='(value, key) in meteor.getyears(thecat)' :value='key'>{{key}} - {{value}} gang(e)</option>
thorus
April 29, 2019, 1:52pm
18
Get thsi error: getyears undefiend
Is it possible to insert the code other places then i
export default {
meteor: {
I’m just not familiar enough with Vue or your code to suggest anything else. Sorry.
thorus
April 30, 2019, 9:03am
20
I’m missing some coding knowledge so its hard to se how it works.
but can you se howto use this filter with the code you made?
https://codepen.io/nordthorus/pen/mggNgZ
instead of:
2019-04-25
2019-04-25
2018-04-25
2019-04-25
it must write:
2019 3 time
2018 1 time
Hope you can help, its the last thing before I can release a beta of a meteor app