How to search single field in mongoDB using querymen? - node.js

Hi I'm currently developing a REST API using this generator.
https://github.com/diegohaz/rest?fbclid=IwAR3FwvhJuKpAtCrywOIRkpts8ZvZ_36Gk9b8ksSv2_MEgFtJnl4G7QZvGNI
But I'm kind of new with the MEAN stack environment especially mongoDB.
I just want to ask how to use the search query parameter described in this auto generated document of my project.
https://www.screencast.com/t/4wR7qyxj5ZP
I'm trying to search all the menu by list_id
for MYSQL something like this.
Select * from menu where list_id = '123';
So this generated REST API application is using querymen for search query. I already tried www.domain.com/menus?q={list_id:"1"}, www.domain.com/menus?q={"list_id":"1"} but none of this works it only shows empty results.
Here's my the router part of the code.
/**
* #api {get} /menus Retrieve menus
* #apiName RetrieveMenus
* #apiGroup Menu
* #apiUse listParams
* #apiSuccess {Object[]} menus List of menus.
* #apiError {Object} 400 Some parameters may contain invalid values.
*/
router.get('/',
query({ limit: { max: 1000 } }),
index)

I'm answering my question just in case someone has the same problem. So I figured out that I just need to include a custom schema in the query parameter so instead of
router.get('/',
query({ limit: { max: 1000 } }),
index)
It is now like this.
query({
list_id: {
type: String,
paths: ['list_id']
},
limit: { max: 1000 }
}),index)
You can also change the String to Regexp if you want.

Related

AfterSubmit and setting field value

I am trying to update a field after a record is submitted but the field is not updating. I know the script is firing because the debug is showing the oldweight value. Can you not update a field in an AfterSubmit userevent.
// 2.0 - Fluent
/**
* #NApiVersion 2.x
* #NScriptType UserEventScript
* #NModuleScope SameAccount
*/
define(["N/record"], function (r) {
function onAfterSubmit(context) {
var oldweight = context.newRecord.getValue({ fieldId: 'custbody93' });
log.debug({
title: 'Old Weight',
details: oldweight
});
if (oldweight) {
var fixWeight = context.newRecord;
context.newRecord.setValue('custbody103', 'oldweight');
};
}
return {
afterSubmit: onAfterSubmit
};
});
In an afterSubmit event, the record has already been submitted and stored in the database, so you cannot update fields directly on the record in memory.
You'll need to use N/record to load() and save() the record or use submitFields() in order to update the database correctly.
Best practice for changing fields on the same record which triggered the User Event is to use beforeSubmit instead; within that entry point, your current code would work as you expect.
I have a video series on understanding User Events and one on how to work with records on my YouTube channel.

executing direct query in controller in loopback

I have started working in loopback 4.I have created a default CRUD controller with basic CRUD operations which can get 'the table data', 'the table record for particular id' etc.. what I need now is I want to execute my own query for this table. How to write a query in controller and execute it?
/* below is the default function to get table data*/
#get('/customers', {
responses: {
'200': {
description: 'Array of customers model instances',
content: {
'application/json': {
schema: {type: 'array', items: {'x-ts-type': Customers}},
},
},
},
},
})
async find(
#param.query.object('filter', getFilterSchemaFor(Customers)) filter?: Filter,
: Promise<Customers[]> {
if (limit > 100) limit = 100; // your logic
return await this.CustomersRepository.find(filter);
}
the type of code I want is,
Execute(dataset, sqlstatement); //is that available?
Support for executing raw database queries was added recently by the pull request #2681, this functionality is provided by Repository method execute.
Please note that they query format is connector-specific. For example, if you are using MySQL database, then you can write the following query:
await this.CustomersRepository.execute(
// the query template, use "?" for variables to AVOID SQL INJECTIONS ATTACKS!
'SELECT TOP ? * FROM CUSTOMERS',
// the values to use for variables
[limit]);

Why is sails.js limiting responses by default?

I created a default sails.js install with all default options on top of a simple mysql database. Currently, I have a table with 91 records.
I have an ionic front end that loads the list in that table, but it's displaying 30 records.
I used postman to hit the sails.js url (http://localhost:1337/list) and that is showing 30 records returned).
While it's a duplicate effort, I hit the url (http://localhost:1337/list) directly in a browser and it still returns 30 records.
Is there a default to how many records sails.js will return?
If so, how do I remove this default so sails.js will return all the results rather than a subset? I don't want to paginate, I want the full list.
PS I have checked the sails.js model I created to verify I don't have any funky limiting stuff and it's uber barebones.
I have no custom code and the entire sails.js install is the default minus the db connection, the skeleton controller, and the models.
Here's my model:
module.exports = {
identity: 'List',
attributes: {
id: {
type: 'integer',
primaryKey: true
},
name: {
type: 'string',
unique: true,
required: true
},
user: {
type: 'integer'
}
}
};
You are using blueprints for find action.
Go inside config/blueprints.js file and check all comments...
There you will find:
/****************************************************************************
* *
* The default number of records to show in the response from a "find" *
* action. Doubles as the default size of populated arrays if populate is *
* true. *
* *
****************************************************************************/
// defaultLimit: 30
Change it as you prefer.

How to do a LEFT JOIN in Sequelize with more than one predicate in the ON clause?

This is my very simple Sequelize model relation:
models["Post"]
.hasMany(models["PostLike"])
models["PostLike"]
.belongsTo(models["Post"])
and this is my Sequelize.findAll query (written in CoffeeScript):
Post.findAll
include : [ PostLike ]
where : where
offset : start
limit : limit
order : order
.success (posts) =>
......
.failure (error) =>
......
As you can see I include the PostLike model and Sequelize produces the correct LEFT JOIN:
...FROM "posts" LEFT JOIN "post_likes" AS "post_likes"
ON "posts"."id" = "posts_likes"."post_id" ...
However, I would like to get Sequelize to extend the ON predicates with my custom criteria:
... ON "posts"."id" = "posts_likes"."post_id" AND posts_likes.author_id = 123
It might be something very easy to do, I just could not find it in the docs.
Thanks
Excuse the lack of CoffeeScript, but you could do something like:
Post.findAll({
include: [{
model: PostLike,
where: { author_id: 123 }
}]
})
I've found the following comments in the code which may also be of use.
* #param {Array<Object|Model>} [options.include] A list of associations to eagerly load using a left join. Supported is either `{ include: [ Model1, Model2, ...]}` or `{ include: [{ model: Model1, as: 'Alias' }]}`. If your association are set up with an `as` (eg. `X.hasMany(Y, { as: 'Z }`, you need to specify Z in the as attribute when eager loading Y).
* #param {Model} [options.include[].model] The model you want to eagerly load
* #param {String} [options.include[].as] The alias of the relation, in case the model you want to eagerly load is aliassed. For `hasOne` / `belongsTo`, this should be the singular name, and for `hasMany`, it should be the plural
* #param {Association} [options.include[].association] The association you want to eagerly load. (This can be used instead of providing a model/as pair)
* #param {Object} [options.include[].where] Where clauses to apply to the child models. Note that this converts the eager load to an inner join, unless you explicitly set `required: false`
* #param {Array<String>} [options.include[].attributes] A list of attributes to select from the child model
* #param {Boolean} [options.include[].required] If true, converts to an inner join, which means that the parent model will only be loaded if it has any matching children. True if `include.where` is set, false otherwise.
* #param {Array<Object|Model>} [options.include[].include] Load further nested related models

Mongoose bidirectional models / many to many relationships

Fairly new to mongoose so I'm looking for the best way to do this. I have two models: Users and Companies. A user can have many companies and a company can have many users.
Right now my Company Schema looks like this:
CompanySchema = new Schema
name:
type: String
unique: true
slug:
type: String
users: [
type: Schema.Types.ObjectId
ref: 'User'
]
And then I can use .populate('users') to get a list of associated users. No problem there.
What I'm wondering is, what is the most efficient/best way to get all companies associated with a user? I don't want to do the same as above as the lists could get out of sync. Is there a way that when I update a company's user that the user's companies are also updated?
Ideally, I could just do User.find().populate('companies')
I haven't found a way to get populate to work both ways.
Normally we end up doing something like this
/**
* Load the categories for this account
* #method categories
* #memberof Account
* #instance
* #param {Function} done
*/
AccountSchema.methods.categories = function (done) {
var Category = this.model('Category');
return Category.find({account: this}, done);
};

Resources