[Op.like]: example from Sequelize documentation throws SQL error - node.js

I have a Node/Express/Sequelize project.
Using the following example from the documentation, it fails and throws a SQL error on MySQL
Image.findAll({
where: {
image_title: {
[Op.like]: { [Op.any]: ['cat', 'hat']}
}
}
})
The above query generates the following SQL in Node/Express:
`Executing (default): SELECT `id`, `story_title`, `image_title`,
`original_filename`, `created_at` AS `createdAt`, `updated_at`
AS `updatedAt` FROM `image`
AS `image`
WHERE `image`.`image_title` LIKE ANY ('cat', 'hat');`
I expected to get a list of images where the image_title contains either 'cat' or 'hat'
Instead, I get a console error in Chrome that reads:
"You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax
to use near '('cat', 'hat')' at line 1"
And no images.
What I'm trying to do is pass an array of strings into a query and return all images where the image_title contains any of the strings in the array.
This example from the documentation seems to be exactly what I'm looking for, but I can't get it to work with even static strings using the documented syntax.
Is there a bug in this, am I misunderstanding how this works, or is there another way to accomplish this?

Possible workaround for now might be to use RegEx
let words = ['cat','hat'];
Image.findAll({
where: {
image_title: {
[Op.regexp]: `*(${words.join('|')})*`
}
}
})

Related

Elastic Search Fielddata error in node.js

I am a very noob and very very very beginner in elastic search, I got this error
StatusCodeError: [illegal_argument_exception] Fielddata is disabled on text fields by default. Set fielddata=true on [time-stamp] in order to load field data in memory by reversing the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.
I saw a few blogs where they mentioned I have to do something like
"field": "user.keyword"
but I tried to put this 1 line snippet in my code, please help me out I don't even know what is field and user in my case/code
my code:
esClient.search({
index:ESindex,
body: {
sort:[{"time-stamp":{"order":"desc"}}],
size:req.query.count,
query: {
match_phrase: { "participant-id":req.query["participant-id"] }
}
}
})

Usage of TSVECTOR and to_tsquery to filter records in Sequelize

I've been trying to get full search text to work for a while now without any success. The current documentation has this example:
[Op.match]: Sequelize.fn('to_tsquery', 'fat & rat') // match text search for strings 'fat' and 'rat' (PG only)
So I've built the following query:
Title.findAll({
where: {
keywords: {
[Op.match]: Sequelize.fn('to_tsquery', 'test')
}
}
})
And keywords is defined as a TSVECTOR field.
keywords: {
type: DataTypes.TSVECTOR,
},
It seems like it's generating the query properly, but I'm not getting the expected results. This is the query that it's being generated by Sequelize:
Executing (default): SELECT "id" FROM "Tests" AS "Test" WHERE "Test"."keywords" ## to_tsquery('test');
And I know that there are multiple records in the database that have 'test' in their vector, such as the following one:
{
"id": 3,
"keywords": "'keyword' 'this' 'test' 'is' 'a'",
}
so I'm unsure as to what's going on. What would be the proper way to search for matches based on a TSVECTOR field?
It's funny, but these days I am also working on the same thing and getting the same problem.
I think part of the solution is here (How to implement PostgresQL tsvector for full-text search using Sequelize?), but I haven't been able to get it to work yet.
If you find examples, I'm interested. Otherwise as soon as I find the solution that works 100% I will update this answer.
What I also notice is when I add data (seeds) from sequelize, it doesn't add the lexemes number after the data of the field in question. Do you have the same behavior ?
last thing, did you create the index ?
CREATE INDEX tsv_idx ON data USING gin(column);

Postgres Node search query using LIKE, how to set %

I have a weird problem I encountered using Postgresql and Node. I would like to use LIKE in my query together with % at the beginning and end of searched term. I have no issue using it in the plain SQL:
THIS WORKS:
SELECT * FROM vehicle WHERE module_imei LIKE '%searchterm%' OR custom_id LIKE '%searchterm%'
However, using it in Node is a bit of challenge. I haven't been successful in resolving it yet:
THIS DOES NOT WORK:
getVehiclesSearch: async function({ search }) {
let response;
try {
response = await pool.query(`SELECT * FROM vehicle WHERE module_imei LIKE %$1% OR custom_id LIKE %$1%`, [search]);
if(response) return response.rows;
} catch(error) {
// handle error
console.error(error);
// do not throw anything
}
},
Doing above will produce: syntax error at or near "%"
SELECT * FROM vehicle WHERE module_imei LIKE '%${$1}%' OR custom_id LIKE '%${$1}%
Doing above will produce: $1 is not defined
SELECT * FROM vehicle WHERE module_imei LIKE '%$1%' OR custom_id LIKE '%$1%'
Doing above will produce: bind message supplies 1 parameters, but prepared statement "" requires 0
I kind of struggle factoring the % in so it won't crash the query. Simply run out of ideas after trying above and variables of those. Thanks for your kind help.
This has been already answered over here:
Go postgresql LIKE query
In this particular case:
response = await pool.query(`SELECT * FROM vehicle WHERE module_imei LIKE '%'||$1||'%' OR custom_id LIKE '%'||$1||'%'`, [search]);
This would work.
You are missing single quotes, also I don't recognize a db adapter you use, but you can use template literals (watch out for sql injection!!!)
response = await pool.query(`SELECT * FROM vehicle WHERE module_imei LIKE '%${search}%' OR custom_id LIKE '%${search}%'`);

using nodejs with pattern matching in CQL

const query= 'SELECT * FROM TEST WHERE "partitionId" = \'sr\' AND "name" LIKE \'%?%\'';
db.execute(query, ['B']).then(function(res) {
console.log(res);
}).catch(function(error) {
console.log(error);
});
I was not able to select data based on the pattern specified in the array.What is the exact way using CQL pattern matching with nodejs.I am getting "Invalid amount of bind variables" error.
NOTE: db has all the connection parameters
I think that you need to use following instead
const query= 'SELECT * FROM TEST WHERE "partitionId" = \'sr\' AND "name" LIKE ?';
db.execute(query, ['%B%']).then(function(res) {
...
P.S. Do you have corresponding indices built that support the LIKE expression? Cassandra doesn't work the same way as "standard" SQL databases.

ArangoDB AQL Upsert how to push a value into list

Trying to use the UPSERT in AQL and successful intill I need to push a value into an list array (and I also need ot check if it exists although I think I have that)
Code
const t_list_ = db._query(aql`
UPSERT { token_name: ${token_i}, type: ${type}}
INSERT { token_name: ${token_i},
type: ${type},
frequency: ${tokens[i].frequency},
user_list: [${req.pathParams.user_id}] }
UPDATE { frequency: OLD.frequency + ${tokens[i].frequency},
user_list: OLD.user_list.push(${req.pathParams.user_id})}
IN token_category
RETURN { doc: NEW, type: OLD ? 'update' : 'insert' }`).toArray()
Error is : ArangoError: syntax error, unexpected (, expecting } near '(#value3)} IN token_category
The language used here is Javascript.
Simplifying the query as used here:
let foo="bar";
db._query(aql`RETURN ${foo}`).toArray()
is actually using a specialized AQL-Template string to generate bind values. To dismantle what is actualy handed into db._query() we may use JSON.stringify():
print(JSON.stringify(aql`RETURN ${foo}`))
{"query":"RETURN #value0","bindVars":{"value0":"bar"}}
here you see where that string came actually from that was there in the error message: #value3 actually is a bind variable for one of the expressions you've inserted into the template.
So the actual line in question of the syntax error is this one:
UPDATE { frequency: OLD.frequency + ${tokens[i].frequency},
user_list: OLD.user_list.push(${req.pathParams.user_id})}
and here you're mixing AQL syntax with Javascript-Syntax, which is not supported.

Resources