I am having three association tables back to back. That means item_level_1 have many item_level_2 and item_level_2 have many item_level_3. I used a search query to find any parent or child having a name containing the search text. That means if I type abc, then I need to return all parent or child with full details(parents and children). But in my case, if item_level_3 has abc in the name, it returns the parent details, but it just only returns the specific child with abc from item_level_3. I need to return all children inside item_level_3 where the same parent.
I am using MySQL database in AWS with node
I checked https://sequelize.org/master/manual/eager-loading.html#complex-where-clauses-at-the-top-level and tried different combinations. But not help. I might miss something. But I cannot find it.
exports.searchItems = (body) => {
return new Promise((resolve, reject) => {
let searchText = body.searchText.toLowerCase();
let limit = body.limit;
let offset = body.offset;
db.item_level_1.findAndCountAll({
where: {
[Sequelize.Op.or]: [
Sequelize.where(Sequelize.fn('lower', Sequelize.col("item_level_1.name")), Sequelize.Op.like, '%' + searchText + '%'),
Sequelize.where(Sequelize.fn('lower', Sequelize.col("item_level_2.name")), Sequelize.Op.like, '%' + searchText + '%'),
Sequelize.where(Sequelize.fn('lower', Sequelize.col("item_level_2.item_level_3.name")), Sequelize.Op.like, '%' + searchText + '%'),
],
[Sequelize.Op.and]: [
Sequelize.where(Sequelize.col("item_level_1.status"), Sequelize.Op.eq, body.status)
]
},
offset: offset,
limit: limit,
distinct: true,
subQuery: false,
attributes: ['id', 'name'],
include: [
{
model: db.item_level_2,
as: 'item_level_2',
where: {
status: body.status
},
attributes: ['id', 'name'],
required: true,
include: [{
model: db.item_level_3,
as: 'item_level_3',
where: {
status: body.status
},
required: false,
attributes: ['id', 'name']
}]
}
]
}).then(result => {
resolve({ [KEY_STATUS]: 1, [KEY_MESSAGE]: "items listed successfully", [KEY_DATA]: result.rows, [KEY_TOTAL_COUNT]: result.count });
}).catch(error => {
reject({ [KEY_STATUS]: 0, [KEY_MESSAGE]: "items list failed", [KEY_ERROR]: error });
});
})
}
Expected result
{
"status": 1,
"message": "Rent items listed successfully",
"data": [
{
"id": 21,
"name": "this is test parent one",
"item_level_2": [
{
"id": 39,
"name": "this is second test parent one",
"item_level_3": {
"id": 9,
"name": "this is the child description with abc"
}
},
{
"id": 40,
"name": "this is second test parent two",
"item_level_3": {
"id": 6,
"name": "this is the child description with def"
}
},
{
"id": 41,
"name": "this is second test parent three",
"item_level_3": {
"id": 70,
"name": "this is the child description with ghi"
}
}
]
}
],
"totalCount": 1
}
Actual result
{
"status": 1,
"message": "Rent items listed successfully",
"data": [
{
"id": 21,
"name": "this is test parent one",
"item_level_2": [
{
"id": 39,
"name": "this is second test parent one",
"item_level_3": {
"id": 9,
"name": "this is the child description with abc"
}
}
]
}
],
"totalCount": 1
}
item_level_1 model
module.exports = (sequelize, DataTypes) => {
const item_level_1 = sequelize.define("item_level_1", {
id: { type: INTEGER, primaryKey: true, autoIncrement: true },
name: { type: STRING },
status: { type: BOOLEAN, defaultValue: 0 }
}, {
timestamps: false,
freezeTableName: true,
})
item_level_1.associate = function (models) {
item_level_1.hasMany(models.item_level_2, { as: 'item_level_2' });
};
return item_level_1;
}
item_level_2 model
module.exports = (sequelize, DataTypes) => {
const item_level_2 = sequelize.define("item_level_2", {
id: { type: INTEGER, primaryKey: true, autoIncrement: true },
name: { type: STRING },
status: { type: BOOLEAN, defaultValue: 0 },
itemLevel2Id: { type: INTEGER },
itemLevel1Id: { type: INTEGER }
}, {
timestamps: false,
freezeTableName: true,
})
item_level_2.associate = function (models) {
item_level_2.belongsTo(models.item_level_3, { as: 'item_level_3', foreignKey: 'itemLevel2Id' });
};
return item_level_2;
}
item_level_2 model
module.exports = (sequelize, DataTypes) => {
const item_level_3 = sequelize.define("item_level_3", {
id: { type: INTEGER, primaryKey: true, autoIncrement: true },
name: { type: STRING },
status: { type: BOOLEAN, defaultValue: 0 }
}, {
timestamps: false,
freezeTableName: true,
})
return item_level_3;
}