-
Notifications
You must be signed in to change notification settings - Fork 25
Distinct #76
Comments
You could add your own query parameter and make the model call based on that query in the hook, setting app.service('users').before({
find(params) {
if(params.query.$distinct) {
return this.Model.find().distinct().then(data => {
hook.result = data;
return hook;
});
}
}
}); |
Thanks so much for the quick response @daffl - By doing it this way, is my understanding correct that it would do 2 DB queries, where the second is unneeded? |
No. If you set the result in a |
Wow, great to know. Thanks again! |
Hi @daffl - I ended up creating a hook like this, which seems to work a treat: /*
* Distinct Search - can only be 1 distinct at a time
* - allows you to URI query like: books?$distinct=author
* ============================================================
*/
exports.searchDistinct = function () {
return function (hook) {
let query = hook.params.query;
// Must be a before hook
if (hook.type !== 'before') {
throw new Error('The \'searchDistinct\' hook should only be used as a \'before\' hook (hooks.searchDistinct).');
}
// Throw error when no field is provided - eg. just users?$distinct
if (query.$distinct === '') {
throw new Error('Missing $distinct: Which field should be distinct? (hooks.searchDistinct)');
}
let distinctValue = query.$distinct || null;
if (distinctValue == null) return hook;
// Remove $distinct param from query (preventing errors)
delete query.$distinct;
return new Promise((resolve, reject) => {
var args = [
{ $match: query || {} },
{ $group: {
_id: "$" + distinctValue,
total: { $sum: 1 }
}}
];
this.Model.aggregate(args)
.then(data => {
hook.result = {
total: data.length || 0,
data,
};
resolve();
}).catch(err => reject(err));
});
}
} This allows you to hit an endpoint like {
"total": 25,
"data": [
{
"_id": "Spain",
"total": 22
},
{
"_id": "Denmark",
"total": 12
}
... |
Awesome, thank you for sharing! Oh, btw, you can probably just |
Thanks @daffl - that's true - although I have the wrapper promise so that I can alter the |
What I meant is that you can write the same thing like this: /*
* Distinct Search - can only be 1 distinct at a time
* - allows you to URI query like: books?$distinct=author
* ============================================================
*/
exports.searchDistinct = function () {
return function (hook) {
let query = hook.params.query;
// Must be a before hook
if (hook.type !== 'before') {
throw new Error('The \'searchDistinct\' hook should only be used as a \'before\' hook (hooks.searchDistinct).');
}
// Throw error when no field is provided - eg. just users?$distinct
if (query.$distinct === '') {
throw new Error('Missing $distinct: Which field should be distinct? (hooks.searchDistinct)');
}
let distinctValue = query.$distinct || null;
if (distinctValue == null) return hook;
// Remove $distinct param from query (preventing errors)
delete query.$distinct;
var args = [
{ $match: query || {} },
{ $group: {
_id: "$" + distinctValue,
total: { $sum: 1 }
}}
];
return this.Model.aggregate(args)
.then(data => {
hook.result = {
total: data.length || 0,
data,
};
return hook;
});
}
} I found that especially when dealing with other calls that return a promise there is usually no need to create a new promise with |
Ah hah! Very helpful, thank you! |
I'm going to try and keep this in mind for reference in case we want to roll this into some common hooks. cc/ @feathersjs/core-team |
I've tagged this as a todo for myself. Please comment on any enhancements, changes, etc you have in mind. |
Hello |
I solved my problem like this.
|
Hi, is it possible to get 'distinct' records through a rest call (e.g. With the mongoose distinct())? Is possible to Perhaps add it via a before hook?
E.g. If I have a collection full of books, and I want to get just the names of all distinct Authors
The text was updated successfully, but these errors were encountered: