Sequelize multi table association query with ORs - javascript

I have to find a field in different tables, that is, I have to check if the search is in different fields of the Customer table, in different fields of the Shops table, and in different fields of the ContactPerson table
The Customer and Persons and Customer Shops tables are 1-N and are associated
My "search" variable is what I wanna find.
This is my code
CustomerPersonsRelation()
CustomerShop()
var result = await CustomerModel.findAll({
...params,
include: [
{model : ShopModel},
{model: ContactPersonModel}
]
})
All is imported don't worry about that.
My Params are these:
{
where: {
$or: [
{
'$Customer.customer_name$': { $like: '%' + search + '%' },
},
{
'$Customer.customer_fiscal_name$': { $like: '%' + search + '%' },
},
{
'$Customer.customer_responsable_name$': { $like: '%' + search + '%' },
},
{
'$Customer.customer_responsable_phone$': { $like: '%' + search + '%' },
},
{
'$Customer.customer_web$': { $like: '%' + search + '%' },
},
{
'$Shops.shop_name$': { $like: '%' + search + '%' },
},
{
'$Shops.shop_phone$': { $like: '%' + search + '%' },
},
{
'$Shops.shop_mobile$': { $like: '%' + search + '%' },
},
{
'$ContactPersons.contactp_name$': { $like: '%' + search + '%' },
},
{
'$ContactPersons.contactp_phone$': { $like: '%' + search + '%' },
},
{
'$ContactPersons.contactp_mobile$': { $like: '%' + search + '%' },
}
]
},
limit: 3
})
}
But that returns this error:
Error : SequelizeDatabaseError: The multi-part identifier "ContactPersons.contactp_mobile" could not be bound. (And this error for all related fields.)
What I can do for that works?

Solved!
After a lot of tests i discovered the error was not in relation and was not in the OR, was in the LIMIT.
After search i solved this adding duplicating: false in includes.
The final code is this:
var result = await CustomerModel.findAll({
include: [
{model : ShopModel, require: true, duplicating: false},
{model: ContactPersonModel, require: true, duplicating: false}
],
...params,
raw
})

Related

Need Some help to refactor or optimize the code in javascript object

I have tried writing the array of objects using ternary but still I am thinking to refactor the common properties between them if someone could help me with this would be helpful.
const{address } = A
data: conditionalValue ? [
{ text: text },
{ building: address },
{ ' ': pincode }
]:
[
{ text: text },
{ building: address },
{ ' ': pincode },
{ 'somevalue': someValue1 },
{ ' ': otherValue},
],
still the { text: text },{ building: address },{ ' ': pincode } objects are same between 2 condition
You can use some destructuring on a array of additional values:
const conditionalValue = false;
const data = [
{ text: 'text' },
{ building: 'address' },
{ ' ': 'pincode' },
...(
conditionalValue
? [{ 'somevalue': 'someValue1' },{ ' ': 'otherValue'}]
: []
)
];
console.log(data);
However, I think it might be cleaner to just push your other values into the data array.

Sequelize search API not working as desired expressJS

I want to search all columns and display the search result.
I am new to sequelize so used this code to do so, However here it is checking for full matches
I want to show details for partial matches also
How do i acheive this ?
router.post("/search-employees", async (req, res) => {
const searchTerm = req.body.searchTerm;
try {
const resp = await employee.findAll({
where: {
[Op.or]: [
{ name: searchTerm },
{ age: searchTerm },
{ country: searchTerm },
{ position: searchTerm },
{ wage: searchTerm },
],
},
});
res.status(200).send(resp);
} catch (e) {
res.status(400).send(e);
}
});
You can use like operation e.g ([OP.LIKE], [OP.ILIKE]). Found Updated query below.
router.post("/search-employees", async (req, res) => {
const searchTerm = req.body.searchTerm;
try {
const resp = await employee.findAll({
where: {
[Op.or]: [
{ name: { [Op.like]: '%' + searchTerm + '%'} },
{ age: { [Op.like]: '%' + searchTerm + '%'} },
{ country: { [Op.like]: '%' + searchTerm + '%'} },
{ position: { [Op.like]: '%' + searchTerm + '%'} },
{ wage: { [Op.like]: '%' + searchTerm + '%'} }
],
},
});
res.status(200).send(resp);
} catch (e) {
res.status(400).send(e);
}
});

Sequelize include nested column: Unknown column in 'where clause'

I am trying to use the Sequelize ORM's feature that allows referring the nested column from the included Models (See Sequelize Docs: Complex where clauses at the top-level). In the docs it states that, I can use $nested.column$ syntax.
The following is what I was trying to do:
let where = { memberId };
if (req.query.search) {
const like = { [Op.like]: `%${req.query.search}%` };
where = {
...where,
[Op.or]: [
{ '$bookItem.serial$': like },
{ '$bookItem.book.name$': like },
{ '$bookItem.book.ISBNCode$': like },
],
};
}
const options = {
where,
include: [
{
model: models.BookItem,
as: 'bookItem',
required: false,
include: [
{
model: models.Book,
as: 'book',
attributes,
required: false,
},
],
},
],
});
const transactions = await models.Borrow.findAll(options);
However, for the code above, I am getting the following error:
"Unknown column 'bookItem.serial' in 'where clause'"
What am I missing?
Full DB Schema: https://dbdiagram.io/d/5e08b6aaedf08a25543f79cb
Is bookitem a Table? Or a Database?
bookItem.serial either represents db.tbl or tbl.column
bookItem.book.name can only represent db.tbl.column
Since bookItem seems to be a database name, then serial must be a table name. At that point, "tablename LIKE ..." is a syntax error.
In your linked documentation books has no name column, change $bookItem.book.name$ to $bookItem.book.title$, and try adding right: true below required: false to create an inner join.
I have corrected this error on my side. Initially, I am writing this query
but now I have rearranged the query and it works
WRONG QUERY
let where = {
[op.and]: [
{ id: partner_id },
{ [op.or]: [
{ '$customers.customer_name$': { [op.like]: '%' + query + '%'} },
{ '$customers.email$': { [op.like]: '%' + query + '%'} },
]},
],
};
// const where = {
// id: partner_id
// }
return await this.deliveryBoys.findOne({
attributes: [
['id', 'partner_id'],
'delivery_boy_name',
'email',
'profile_picture',
'phone_number',
'fcm_token',
],
include: [
{
model: this.customers,
as: 'customers',
attributes: ['id', 'customer_name', 'email', 'profile_picture', 'phone_number'],
require: true,
where: {
customer_name: {
[op.like]: '%' + query + '%'
}
},
include: [
{
model: this.company,
as: 'company',
},
{
model: this.address,
as: 'address',
required: false,
where: {
status: 1
}
}
]
},
],
where,
});
FINAL WORKING QUERY
let where = {
[op.and]: [
{ '$deliveryBoys.id$': partner_id },
{ [op.or]: [
{ '$customers.email$': { [op.like]: '%' + query + '%'} },
{ '$customers.customer_name$': { [op.like]: '%' + query + '%'} },
{ '$customers.phone_number$': { [op.like]: '%' + query + '%'} },
{ '$company.name$': { [op.like]: '%' + query + '%'} },
]},
],
};
return await this.customers.findAll({
attributes: ['id', 'customer_name', 'email', 'profile_picture', 'phone_number'],
include:[
{
model: this.deliveryBoys,
as: 'deliveryBoys',
attributes: ['id','delivery_boy_name','phone_number','email','profile_picture','status',],
where:{
id: partner_id
}
},
{
model: this.company,
as: 'company',
},
{
model: this.address,
as: 'address',
required: false,
where: {
status: 1
}
}
],
where
});

how to search string in whole string in loopback query

I want search whole string when I type any word, it's matched only first Character not matched whole string and middle character of string.
query.and.push({ or: [{ name: { like: '^' + data.searchTextNEM + '.*', options: 'i' } }, { email: { like: '^' + data.searchTextNEM + '.*', options: 'i' } },{ phone: { like: '^' + data.searchTextNEM + '.*', options: 'i' } }]});
Users.find({where: query, limit: data.limit,skip: data.skip },function(err,res){})
Like I have two string 1.mark and 2.denim if I type 'm' my response should be mark and denim but getting response only mark
You may have try this:-
name: { ilike: '%' + data.searchTextNEM + '%' }
It will also match with case insensitive text.
or:
you may have pass the options in like filter:-
?filter={"where":{"title":{"like":"someth.*","options":"i"}}}
I think your regex is incorrect. If you insert 'm' your regex becomes ^m.* which means "starts with m and then has any number of any characters". I think you want .*m.* which means "has any number of any character, then an m, then any number of any character":
query.and.push({ or: [{ name: { like: '.*' + data.searchTextNEM + '.*', options: 'i' } }, { email: { like: '.*' + data.searchTextNEM + '.*', options: 'i' } },{ phone: { like: '.*' + data.searchTextNEM + '.*', options: 'i' } }]});
Users.find({where: query, limit: data.limit,skip: data.skip },function(err,res){
})

x-editable custom fields cannot get text of select menu

Ive followed this example from another SO thread:
X-editable custom field type not respecting overridden defaults
and its helped me to create a similar custom field with x-editable. All is working ok but i cant figure out how render/display the 'text' of the select - the SO example ouputs the 'value'. my js to initialis the x-editable to use my custom inputs is thus:
$('#stffulladdress').editable({
url : '',
pk : 6,
value : {
address : "",
city : "",
region : "",
postcode : "",
country : "eng"
},
sourceCountry: [
{ value: "eng", text: "ENGLAND" },
{ value: "ire", text: "IRELAND" },
{ value: "sco", text: "SCOTLAND" },
{ value: "cym", text: "WALES" }
],
validate : function(value) {
if (value.address == '' || value.postcode == '') return "Address first lines AND Postcode required";
},
display : function(value) {
if (!value) {
$(this).empty();
return;
}
console.log(value.country);
var html = $('<div>').html( value.address + '<br />' + value.city + '<br />' + value.region + '<br />' + value.postcode + '<br />' + value.country );
$(this).html(html);
}
});
My custom x-editable class is the same as the SO example mentioned with the only difference being i have more inputs -they work ok as expected. I would have thought that this snippet from the x-edit class gets the text of the selected item:
value2html: function(value, element) {
if(!value) {
$(element).empty();
return;
}
var countryText = value.country;
$.each(this.sourceCountryData, function (i, v) {
if (v.value == countryText) {
countryText = v.text.toUpperCase();
}
});
var html = $('<div>').html( value.address + ',<br />' + value.city + ',<br />' + value.region + ',<br />' + value.postcode + ',<br />' + countryText );
$(element).html(html);
},
But upn displaying the selected country i still get the country value "eng" and not the text "England".
I've tried :
value.country which gives me the value 'eng'
and value.text gives undefined
Any idea how i can get the selected text??
thanks
Try the sourceCountry as follow:
sourceCountry: [
{ "eng": "ENGLAND" },
{ "ire": "IRELAND" },
{ "sco": "SCOTLAND" },
{ "cym": "WALES" }
],

Categories

Resources