MySQL Forums
Forum List  »  PHP

Search rows and order by column and position of keywords in the results
Posted by: Dacian Nicoara
Date: February 28, 2020 03:45PM

Hello everyone!

I bumped my head into an issue and I need your help to solve it. My context is as following:

I have a table that stores records with a basic structure that looks like this (there are some other columns but these are used in the current issue):

```
|---|----|-------------------------------------------------|----------------------------------------------------------------------------------|
|ID |type|title | description |
|---|----|-------------------------------------------------|----------------------------------------------------------------------------------|
| 1 | 0 | Lorem ipsum keyword_1 dolor keyword_2 keyword_3 | Mauris faucibus, keyword_2 odio keyword_1 gravida keyword_3, lacus leo malesuada |
|---|----|-------------------------------------------------|----------------------------------------------------------------------------------|
| 2 | 0 | Lorem ipsum keyword_1 dolor keyword_2 | Mauris faucibus, odio keyword_1 gravida keyword_3, lacus leo malesuada |
|---|----|-------------------------------------------------|----------------------------------------------------------------------------------|
| 3 | 1 | keyword_1 Lorem ipsum dolor keyword_2 | Mauris keyword_1 faucibus, odio keyword_2 gravida keyword_3, lacus leo malesuada |
|---|----|-------------------------------------------------|----------------------------------------------------------------------------------|
| 4 | 0 | Lorem ipsum keyword_1 dolor keyword_2 keyword_3 | Mauris faucibus, keyword_2 odio keyword_1 gravida keyword_3, lacus leo malesuada |
|---|----|-------------------------------------------------|----------------------------------------------------------------------------------|
| 5 | 0 | Lorem ipsum keyword_1 dolor keyword_2 | Mauris faucibus, odio keyword_1 gravida keyword_3, lacus leo malesuada |
|---|----|-------------------------------------------------|----------------------------------------------------------------------------------|
| 6 | 1 | keyword_1 Lorem ipsum dolor keyword_2 | Mauris keyword_1 faucibus, odio keyword_2 gravida keyword_3, lacus leo malesuada |
|---|----|-------------------------------------------------|----------------------------------------------------------------------------------|
| 7 | 0 | keyword_1 keyword_2 keyword_3 Lorem ipsum dolor | keyword_1 keyword_2 Mauris faucibus, odio keyword_3 gravida, lacus leo malesuada |
|---|----|-------------------------------------------------|----------------------------------------------------------------------------------|
```
...and so on.

+ the *ID* column is auto_increment
+ the *type* column is int(1) with only two possible values: 0 or 1
+ the *title* column is varchar(255)
+ the *description* column is mediumtext

An user performs a search for "*keyword_1 keyword_2 keyword_3*" or "*keyword_1 keyword_2*" or "*keyword_1*" and I would like to get the results with a query that is respecting the following conditions:

1. it should return the rows with type=0 first
2. it should return the rows that contain all the keywords in title and / or description (either the *title* or the *description* (or both) should contain all the keywords entered by the user)
3. it should return first the rows in which the position of the keywords is the most to the left (the beggining of the string stored in the table) on each of the two columns (*title* and / or *description*)
4. foreach of the keywords, it should match only the whole word (I don't want results with *keyword_1andsomeotherchars*)
5. **Update** if `type` = 0 then search only in `title` else search in `title` or `description`

A pseudo-query would be something like
```
select * from table
where title and / or description contains all the keywords
and keywords are most to the beginig of title and or description
order by type asc and by position of keywords in title and / or description
```

Currently, my query looks like this:

```
SELECT *
FROM table
WHERE table.`type` IN ('0','1')
AND table.`approved` = 1
AND table.`trash` = 0
AND ((table.`type` = 0
AND (match(table.`title`) against ('+keyword_1' IN BOOLEAN MODE)
AND match(table.`title`) against ('+keyword_2' IN BOOLEAN MODE)
AND match(table.`title`) against ('+keyword_3' IN BOOLEAN MODE))
OR table.`title` REGEXP '\bkeyword_1 keyword_2 keyword_3\b')
OR (table.`type` = 1
AND ((match(table.`title`) against ('+keyword_1' IN BOOLEAN MODE)
AND match(table.`title`) against ('+keyword_2' IN BOOLEAN MODE)
AND match(table.`title`) against ('+keyword_3' IN BOOLEAN MODE))
OR (match(table.`description`) against ('+keyword_1' IN BOOLEAN MODE)
AND match(table.`description`) against ('+keyword_2' IN BOOLEAN MODE)
AND match(table.`description`) against ('+keyword_3' IN BOOLEAN MODE)))
OR (table.`title` REGEXP '\bkeyword_1 keyword_2 keyword_3\b'
OR table.`description` REGEXP '\bkeyword_1 keyword_2 keyword_3\b'))
OR (table.`type` = 1
AND ((table.`title` REGEXP '\bkeyword_1\b'
OR table.`title` REGEXP '\bkeyword_2\b'
OR table.`title` REGEXP '\bkeyword_3\b')
AND (table.`description` REGEXP '\bkeyword_1\b'
AND table.`description` REGEXP '\bkeyword_2\b'
AND table.`description` REGEXP '\bkeyword_3\b'))))
ORDER BY table.`type` ASC,
CASE
WHEN table.`type` = 0 THEN INSTR(table.`title`, 'keyword_1 keyword_2 keyword_3')
WHEN table.`type` = 1 THEN INSTR(concat(table.`title`, table.`description`), 'keyword_1 keyword_2 keyword_3')
END ASC
LIMIT 0,20
```

but I'm not getting what I wanted. Can anyone help me solve this?

Thank you, in advance, for your time and help!

Options: ReplyQuote


Subject
Written By
Posted
Search rows and order by column and position of keywords in the results
February 28, 2020 03:45PM


Sorry, you can't reply to this topic. It has been closed.

Content reproduced on this site is the property of the respective copyright holders. It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.