![Introducing Enhanced Alert Actions and Triage Functionality](https://cdn.sanity.io/images/cgdhsj6q/production/fe71306d515f85de6139b46745ea7180362324f0-2530x946.png?w=800&fit=max&auto=format)
Product
Introducing Enhanced Alert Actions and Triage Functionality
Socket now supports four distinct alert actions instead of the previous two, and alert triaging allows users to override the actions taken for all individual alerts.
advanced-results
Advanced tools
Readme
Middleware used for advanced querying Mongoose Documents for a specific Model trough GET request using the queries and parametars prvoided by the url . It only works with MongoDB (mongoose) and expressjs. It also provides pagination
Benefits:
Additional examples about this middleware: HERE
$ npm install advanced-results@latest
ES6 syntax:
import advancedResults from 'advanced-results'
ES5 syntax:
const advancedResults = require('advanced-results');
Advanced-results middleware is very easy to implement you just use it in the route right before your main controller/middleware: Ex.
const app = express();
app.use('/posts', advancedResults(Model), (req, res) => {
// The result for the advancedResults middleware is store inside res.advancedResults
res.status(200).json({ success:true, data: res.advancedResults })
});
The results and the chosen documents are stored inside res.advancedResults. Ex num2.
const router = express.router();
router.get('/posts', advancedResults(Model), (req, res) => {
// The result for the advancedResults middleware is store inside res.advancedResults
res.status(200).json(res.advancedResults)
});
This middleware works thanks to the express request object and uses req.query and req.params.
As a first argument advancedResults(MODEL), accepts a mongoose model that will be the target for the advanced querying.
Example scenario:
const UserSchema = new mongoose.Schema({
name: String,
user: String,
randomNum: Number,
});
const User = mongoose.model('User', UserSchema);
await model.insertMany([
{ name: 'Tester', user: 'Tester', randomNum: 4 },
{ name: 'Tester2', user: 'Tester2', randomNum: 54 },
{ name: 'Tester3', user: 'Tester3', randomNum: 42 },
]);
app.use(
'/users',
advancedResults(User),
(req, res: any) => {
res.status(200).json(res.advancedResults);
}
);
FOR URL: example.com?name=Tester
OUTPUT: res.advancedResults = {
success: true,
count: 1,
pagination: { pages: 1, total: 1, maxDocuments: 3, current: 1, limit: 6 },
data: [
{
_id: 5fa47738c49e1327502760ca,
name: 'Tester',
user: 'Tester',
randomNum: 4,
__v: 0
}
]
}
FOR URL: example.com?name[regex]=Tester
OUTPUT: res.advancedResults = {
success: true,
count: 3,
pagination: { pages: 1, total: 3, maxDocuments: 3, current: 1, limit: 6 },
data: [
{
_id: 5fa47738c49e1327502760ca,
name: 'Tester',
user: 'Tester',
randomNum: 4,
__v: 0
},
{
_id: 5fa47738c49e1327502760cb,
name: 'Tester2',
user: 'Tester2',
randomNum: 54,
__v: 0
},
{
_id: 5fa47738c49e1327502760cc,
name: 'Tester3',
user: 'Tester3',
randomNum: 42,
__v: 0
}
]
}
FOR URL: example.com?name[regex]=Tester&select=name
OUTPUT: res.advancedResults = {
success: true,
count: 3,
pagination: { pages: 1, total: 3, maxDocuments: 3, current: 1, limit: 6 },
data: [
{ _id: 5fa47738c49e1327502760ca, name: 'Tester' },
{ _id: 5fa47738c49e1327502760cb, name: 'Tester2' },
{ _id: 5fa47738c49e1327502760cc, name: 'Tester3' }
]
}
Urls also work with some special fields: all, q and filter
Example 1.
FOR URL: example.com?all=42
OUTPUT: res.advancedResults = {
success: true,
count: 1,
pagination: { pages: 1, total: 1, maxDocuments: 3, current: 1, limit: 6 },
data: [
{
_id: 5fa47738c49e1327502760cc,
name: 'Tester3',
user: 'Tester3',
randomNum: 42,
__v: 0
}
]
}
?all or ?q fields are basically the same and they are used for searching trough all paths and subpaths of the provided model. For the query above where ?all=42 here's what was given to the model.find() function:
model.find({ '$or': [ { randomNum: 42 }, { __v: 42 } ] })
Example 2 for ?all or ?q:
FOR URL: example.com?all=test&select=name&sort=name
QUERY PASSED TO MODEL(USER in our case):
model.find("$or":[{"name":{"$regex":"test","$options":"i"}},{"user":{"$regex":"test","$options":"i"}}])
OUTPUT: res.advancedResults = {
success: true,
count: 3,
pagination: { pages: 1, total: 3, maxDocuments: 3, current: 1, limit: 6 },
data: [
{ _id: 5fa47738c49e1327502760ca, name: 'Tester' },
{ _id: 5fa47738c49e1327502760cb, name: 'Tester2' },
{ _id: 5fa47738c49e1327502760cc, name: 'Tester3' }
]
}
?filter is more complicated query parametar and requires more parsing before it's sent to the backend. I intially created this option because of react-admin package. You can find more example on how to use this HERE
advancedResults except model as first parametar it takes 3 more arguments
advancedResults(Model, populateFieldOrFields: string | string[], parametar: [string, string], consoleLogIt: boolean)
In this section i will mention most of the options you can pass to the URL that will work with this middleware
Check MongoDB documentation about querying, operators and options in order to understand more about this middleware. Here's basic explanation for some of the options :
Operator | Description |
---|---|
in | selects the documents where the value of a field equals any value in the specified array , ex. ?field[in]=value1,value2 |
regex | provides regular expression capabilities for pattern matching strings in queries. By default is in-case sensitive but can be changed with the $options operator, ex. ?field[regex]=sth) |
options | this only works with regex. By default is case-insensitivite ex. ?field[regex]=val&field[options]=i |
gt | example.com?field[gt]=5 |
gte | example.com?field[gte]=5 |
lt | example.com?field[lt]=5 |
lte | example.com?field[lte]=5 |
eq | example.com?field[eq]=5 |
Special operations that can be done via url:
Operations | Description |
---|---|
select | selects single or multiple fields from a document, example.com?select=field or multiple example.com?select=field1,field2 |
sort | Default field: createdAt, example.com?sort=field. Field can be ?sort=name (ASC Order) or ?sort=-name (DSC Order) |
limit | default: 6, used for limiting documents affects pagination object inside res.advancedResults, example.com?limit=5 |
page | default: 1, the current page if there are multiple pages, this uses limit in order to calculate and represents the current property inside pagination object of res.advancedResults, ex. example.com?page=2 |
all or q | used for searching trough all fields of provided model for a certain value provided in the url, ex. example.com?all=value or multiple words example.com?all=value1+value2 |
filter | more complex then the other 2, it requires additional parsing before sending request to backend to work. Short explanation: filter is an object that first needs to be JSON.stringified then using library like query-parser, parsed INTO url then sent to the backend. Check this additional explanation for usage |
Usually res.advancedResults is provided in the next form:
res.advancedResults = {
success: true,
count: 3,
pagination: {
pages: 3,
total: 9,
maxDocuments: 3,
next: { nextPage: undefined, page: 2 },
current: 1,
limit: 1
},
data: [
{
_id: 5fa47738c49e1327502760ca,
name: 'Tester',
user: 'Tester',
randomNum: 4,
__v: 0
},
{
_id: 5fa47738c49e1327502760cb,
name: 'Tester2',
user: 'Tester2',
randomNum: 54,
__v: 0
},
{
_id: 5fa47738c49e1327502760cc,
name: 'Tester3',
user: 'Tester3',
randomNum: 42,
__v: 0
}
]
}
If you have ?all=word1+word2 it does query for every field for word1 + for word2 + both words "word1 word2" and merges them together into a single object which is then passed to model.find()
I would encourage you to install this middleware and enable the console log option which is the fourth argument and see what it returns and what will be taken into consideration when querying.
If this middleware throws error it will automatically call next(new Error) which will then go to your error middleware handler. Check expressjs error handling page where it teaches you how to define error middleware to handle all types of error and return them into the res object back to the client
Instead of manually adding let's say parametars to url example: localhost?name=Tester1&select=name. You can do that with stringified object. Here's how you do that:
const query = {
all: "Test",
select: "name",
page: "2"
}
Now you need to use additional library like query-string to stringify object to be transformed into valid url parametars
const queryString = require('query-string');
const url = `http://localhost:5000?${queryString.stringify(query)}`;
await axios.get(url);
The query string transforms my url variable to -> http://localhost:5005?all=Test&select=name&page=2 accordingly
CHECK THE ADDITIONAL DOCS FOR MANY MORE EXAMPLES AND EXPLANATION ON HOW TO USE THE ?filter PARAMETAR
FAQs
Advanced query middleware for expressjs and mongoose
The npm package advanced-results receives a total of 4 weekly downloads. As such, advanced-results popularity was classified as not popular.
We found that advanced-results demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket now supports four distinct alert actions instead of the previous two, and alert triaging allows users to override the actions taken for all individual alerts.
Security News
Polyfill.io has been serving malware for months via its CDN, after the project's open source maintainer sold the service to a company based in China.
Security News
OpenSSF is warning open source maintainers to stay vigilant against reputation farming on GitHub, where users artificially inflate their status by manipulating interactions on closed issues and PRs.