How to perform a like query TypeORM
JavascriptTypescriptTypeormJavascript Problem Overview
Hello guys I'm trying to find all the results that have a in them. I have tried a couple of ways but the problem is nothing works. It just returns an empty array
var data = await getRepository(User)
.createQueryBuilder("user")
.where("user.firstName = %:name%", { name: firstName })
.getMany();
and something like this
var data = await getRepository(User)
.createQueryBuilder("user")
.where("user.firstName like %:name%", { name: firstName })
.getMany();
but nothing is working. All of these are returning me a empty array. Can somebody help me out thanks
Javascript Solutions
Solution 1 - Javascript
Correct way is:
var data = await getRepository(User)
.createQueryBuilder("user")
.where("user.firstName like :name", { name:`%${firstName}%` })
.getMany();
Solution 2 - Javascript
TypeORM provides out of the box Like
function. Example from their docs:
import {Like} from "typeorm";
const loadedPosts = await connection.getRepository(Post).find({
title: Like("%out #%")
});
in your case:
var data = await getRepository(User).find({
name: Like(`%${firstName}%`)
});
Solution 3 - Javascript
You can also use the database function for concatenation. In postgres for instance:
var data = await getRepository(User)
.createQueryBuilder("user")
.where("user.firstName like '%' || :name || '%'", {name: firstName })
.getMany();
Solution 4 - Javascript
It seems that all of the answers as of writing including the accepted answer by pleerock are vulnerable to SQL injection unless the user input has been sanitized beforehand.
var data = await getRepository(User)
.createQueryBuilder("user")
.where("user.firstName like :name", { name:`%${firstName}%`})
.getMany();
The fact that the above code is valid in TypeORM makes it so that any query of this style is vulnerable to data exfiltration. Imagining the following similar query:
const data = await getRepository(User)
.createQueryBuilder("user")
.where("user.firstName like :name", { name: firstName })
.getOne();
Un-sanitized data coming in from the user containing %
character being sent into firstName
in the above query (e.g. let firstName = '%John'
) would allow a user to exfiltrate potentially private data about other users.
Hence, where the use case allows one should ensure that any user input is sanitized and any special characters are removed.
Alternatively, in MySQL, where the use case demands that special characters are present in the text a full text search may be more appropriate. However, this is more expensive to maintain.
Create fulltext search on relevant column and perform query
export class User {
@PrimaryGeneratedColumn()
id: number;
@Index({fulltext: true})
@Column()
name: string;
}
const data = await this.repository
.createQueryBuilder()
.select()
.where('MATCH(name) AGAINST (:name IN BOOLEAN MODE)', {name: name})
.getOne()
Solution 5 - Javascript
var data = await getRepository(User)
.createQueryBuilder("user")
.where("user.firstName ILIKE %q, {q:`%${VALUE_HERE}%` })
.getMany();
This is how I do it. Hope it helps
Solution 6 - Javascript
using repositories i put it in the where for exemple :
await this.userRepository.findAndCount({
relations: ['roles', 'company'],
where: `(username like '%${seachValue}%' or firstname like '%${seachValue}%'
or lastname like '%${seachValue}%' or email like '%${seachValue}%')`,
order: {
[sortField]: sortDirection,
},
});