Redisearch query with partial match - redisearch

I'm encountering a little issue with the FT.SEARCH command from redisearch:
For this data whose value is this one: ns=2;s=OIGateway:ArchestrA.ACU.AO_ACU230_AIn_CabTp.fa_A2OutOfRan
How come this query:
FT.SEARCH index 'ns 2 s oigateway archestra acu ao_acu230_ain_cabtp fa_a2o* '
Will return the result
Whereas this one:
FT.SEARCH index 'ns 2 s oigateway archestra acu ao_acu230_ain_cabtp fa_a2* '
(Notice the missing 'o' at the end)
Will return nothing?
Thank you for your replies.

The second query should return all the results from the first one, or more since the prefix might include more results.
Can it be the fact that the first query runs on index while the second runs on glossary.

I ended up learning that redisearch doesn't allow partial search (I mean not like the partial search in sql database LIKE '%hello%')

Related

MySQL SUBSTR LOCATE multi-search-strings

Tricky one, and my brain is mush after staring at my screen for about an hour.
I'm trying to query my database to return the first part of a string (domain name eg. http://www.example.com) in the column image_link.
I have managed this for all rows where the image_link contains .com as part of the string... but I need the code to be more versatile, so it searches for the likes of .net and .co.uk too.
Had thought some sort of nested REPLACE might work, but it doesn't make sense when I try to apply it - and I'm stuck.
Query Builder code:
$builder->select("SUBSTRING(image_link, 1, LOCATE('.com', image_link) + 3) AS domain");
Example strings, with desired results:
http://www.example.com/brands/567.jpg // http://www.example.com
https://www.example.org/photo.png // https://www.example.org
http://example.net/789 // http://example.net
Any help/advice warmly welcomed!
SELECT ... ,
SUBSTRING_INDEX(image_link, '/', 3) domain
FROM test;
Or, if protocol may be absent, then
SELECT ... ,
SUBSTRING_INDEX(image_link, '/', CASE WHEN LOCATE('//', image_link) THEN 3 ELSE 1 END) domain
FROM test;
fiddle

Sqlinjection in where Clause

I am testing an application and encountered a bit unique issue I have found that application is sending parameters like
?$filter=ModuleName+ne+'Bookings'+and+ModuleName+eq+'Transport'+and+(ContactID+eq+null+and+IsToBeShown+eq+true)+&$orderby=ReportName
Obviously I can add and +1+eq+1 and all results are shown but if I try to terminate the query like using (;, or ') it gives me error.
Kind of not sure how to terminate the query and add a union etc. clause to extract data .
Any thoughts are welcome
It seams that $filter is used in where clause and probably is added to some other hard coded conditions. To get all the result you need to add or 1 eq 1 (or instead of and).
It may make a difference if other condidions are added before or after $filter.
Try $filter=union all select ... where 1 eq 1 but remember that column list must be the same in all unioned queries. You don't need to terminate the query with ;
Replace spaces with +, I wrote spaces to make it easier to read.

Explain COUNT query with ActiveRecord

I want to do something like the following:
Post.count.explain # doesn't work
This fails because EXPLAIN is a method on Relation and Post.count isn't a relation. It's just a regular integer that is the result of the query. So how could a count query be EXPLAINed?
Here's a form that generates the exact same SQL query, but returns a Relation to call explain on:
Post.select('count(*)').explain
Both generate the SQL
SELECT COUNT(*) FROM `posts`
...so the query plan should be the same.
From ActiveRecord::Relation#explain, we can make that method accept a block.
module ExplainBlock
def explain_block(&block)
exec_explain(collecting_queries_for_explain { instance_exec(&block) })
end
end
ActiveRecord::Relation.include(ExplainBlock)
Then Post.all.explain_block { count } .
The COUNT shouldn't affect the query plan, since the only difference it does is to tell the database to fetch the row data, but the rows need to be found anyway with/without the COUNT.

nested "select " query in mysql

hi i am executing nested "select" query in mysql .
the query is
SELECT `btitle` FROM `backlog` WHERE `bid` in (SELECT `abacklog_id` FROM `asprint` WHERE `aid`=184 )
I am not getting expected answer by the above query. If I execute:
SELECT abacklog_id FROM asprint WHERE aid=184
separately
I will get abacklog_id as 42,43,44,45;
So if again I execute:
SELECT `btitle` FROM `backlog` WHERE `bid` in(42,43,44,45)
I will get btitle as scrum1 scrum2 scrum3 msoffice
But if I combine those queries I will get only scrum1 remaining 3 atitle will not get.
You Can Try As Like Following...
SELECT `age_backlog`.`ab_title` FROM `age_backlog` LEFT JOIN `age_sprint` ON `age_backlog`.`ab_id` = `age_sprint`.`as_backlog_id` WHERE `age_sprint`.`as_id` = 184
By using this query you will get result with loop . You will be able to get all result with same by place with comma separated by using IMPLODE function ..
May it will be helpful for you... If you get any error , Please inform me...
What you did is to store comma separated values in age_sprint.as_backlog_id, right?
Your query actually becomes
SELECT `ab_title` FROM `age_backlog` WHERE `ab_id` IN ('42,43,44,45')
Note the ' in the IN() function. You don't get separate numbers, you get one string.
Now, when you do
SELECT CAST('42,43,44,45' AS SIGNED)
which basically is the implicit cast MySQL does, the result is 42. That's why you just get scrum1 as result.
You can search for dozens of answers to this problem here on SO.
You should never ever store comma separated values in a database. It violates the first normal form. In most cases databases are in third normal form or BCNF or even higher. Lower normal forms are just used in some special cases to get the most performance, usually for reporting issues. Not for actually working with data. You want 1 row for every as_backlog_id.
Again, your primary goal should be to get a better database design, not to write some crazy functions to get each comma separated number out of the field.

MySQL using table columns in function to create alias to be used in sorting

It sounds more complicated than it actually is. Here is what I'm trying to do within the SELECT part:
SELECT TIMESTAMPADD(
UCASE(
SUBSTRING(offset_unit,1,CHAR_LENGTH(offset_unit)-1)
),1,'2003-01-02') as offset_date
offset_unit is a VARCHAR column in the database. It contains one of the following: "Hours","Minutes".
offset is an INT.
I am trying to convert the offset_unit to uppercase, after I have removed the last character ('s') so I can have a proper interval (MINUTE, HOUR...) so I can get a date that I can use in sorting afterwards, but MySQL keeps throwing an error. I have tested each step by adding one function at a time, and it only fails after I add TIMESTAMPADD. If I enter MINUTE manually then it works.
Any way to get this working?
Additional info: I am running this in CakePHP 1.3, in a find, within the 'fields' array, but that shouldn't be important.
this can be easily achived by using CASE WHEN clause as:
SELECT (CASE
WHEN offset_unit = 'HOURS'
THEN TIMESTAMPADD(HOUR,`offset`,'2003-01-02')
WHEN offset_unit = 'MINUTES'
THEN TIMESTAMPADD(MINUTE,`offset`,'2003-01-02')
END) AS offset_date
FROM my_table;
SEE SQLFIDDLE DEMO HERE
It doesn't work because TIMESTAMPADD does not take a string as the first argument, but a unit keyword, for example MINUTE. My guess is that you need to do this in two steps, first get the unit and then construct a query with the correct keyword.