NOT LIKE = NOT AGAINST ?

12
D
На сайте с 28.06.2008
Offline
1114
981

Че то не могу нагуглить есть ли вообще конструкция NOT AGAINST ?

У меня сложный запрос с LIKE + NOT LIKE. LIKE %% я заменил AGAINST, стало быстрее, а как заменить NOT LIKE ?

AS
На сайте с 12.12.2017
Offline
6
#1

https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html

Вроде как надо знак минус добавить что NOT получить.

SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('-YourSQL' IN BOOLEAN MODE);

[umka]
На сайте с 25.05.2008
Offline
456
#2

… where not match …

Лог в помощь!
Skom
На сайте с 02.12.2006
Offline
165
#3

Совершенно верно

WHERE Чёто_там LIKE '%Голова%' AND Чёто_там NOT LIKE '%Ноги%'

превращаются в

WHERE MATCH (Чёто_там) AGAINST ('+Голова -Ноги' IN BOOLEAN MODE)

Cras amet qui numquam amavit quique amavit cras amet
D
На сайте с 28.06.2008
Offline
1114
#4

Запрос переписал - это ускорило его в 5 раз, но результат разный.

Может ли логика работы LIKE и AGAINST отличаться?

Изначальный запрос:

(SELECT 0 AS level, t1.*,
CONCAT_WS('-', t1.id, t1.alias) AS item_alias,
CONCAT_WS('-', t2.id, t2.alias) AS section_alias
FROM 13_cons_items AS t1
INNER JOIN 13_cons_sections AS t2 ON t1.section_id = t2.id
WHERE t1.parent_id = 0
AND t1.status = 1
AND t1.id != '13069'
AND t1.section_id = '17'
AND (t1.name LIKE '%Аномалия%' OR t1.name
LIKE '%Арнольда%' OR t1.name
LIKE '%Киари%' OR t1.name
LIKE '%ст%' OR t1.name
LIKE '%и%' OR t1.name LIKE '%Аспаркам%'))
UNION (SELECT 1 AS level, t1.*,
CONCAT_WS('-', t1.id, t1.alias) AS item_alias,
CONCAT_WS('-', t2.id, t2.alias) AS section_alias
FROM 13_cons_items AS t1
INNER JOIN 13_cons_sections AS t2 ON t1.section_id = t2.id
WHERE t1.parent_id = 0 AND t1.status = 1 AND t1.id != '13069' AND t1.section_id = '17' AND t1.name
NOT LIKE '%Аномалия%' AND t1.name
NOT LIKE '%Арнольда%' AND t1.name
NOT LIKE '%Киари%' AND t1.name
NOT LIKE '%ст%' AND t1.name
NOT LIKE '%и%' AND t1.name NOT LIKE '%Аспаркам%')
ORDER BY level ASC LIMIT 3

Измененный запрос

(SELECT 0 AS level, t1.*,
CONCAT_WS('-', t1.id, t1.alias) AS item_alias,
CONCAT_WS('-', t2.id, t2.alias) AS section_alias
FROM 13_cons_items AS t1
INNER JOIN 13_cons_sections AS t2 ON t1.section_id = t2.id
WHERE t1.parent_id = 0
AND t1.status = 1
AND t1.id != '13069'
AND t1.section_id = '17'
AND ( MATCH (t1.name)
AGAINST ('Аномалия') OR MATCH (t1.name)
AGAINST ('Арнольда') OR MATCH (t1.name)
AGAINST ('Киари') OR MATCH (t1.name)
AGAINST ('ст') OR MATCH (t1.name)
AGAINST ('и') OR MATCH (t1.name)
AGAINST ('Аспаркам')))
UNION (SELECT 1 AS level, t1.*,
CONCAT_WS('-', t1.id, t1.alias) AS item_alias,
CONCAT_WS('-', t2.id, t2.alias) AS section_alias
FROM 13_cons_items AS t1
INNER JOIN 13_cons_sections AS t2 ON t1.section_id = t2.id
WHERE t1.parent_id = 0 AND t1.status = 1 AND t1.id != '13069' AND t1.section_id = '17'
AND MATCH (t1.name) AGAINST ('-Аномалия' IN BOOLEAN MODE)
AND MATCH (t1.name) AGAINST ('-Арнольда' IN BOOLEAN MODE)
AND MATCH (t1.name) AGAINST ('-Киари' IN BOOLEAN MODE)
AND MATCH (t1.name) AGAINST ('-ст' IN BOOLEAN MODE)
AND MATCH (t1.name) AGAINST ('-и' IN BOOLEAN MODE)
AND MATCH (t1.name) AGAINST ('-Аспаркам' IN BOOLEAN MODE))
ORDER BY level ASC LIMIT 3
[umka]
На сайте с 25.05.2008
Offline
456
#5

match … against как минимум не учитывает "ст" и "и", и любые слова, длина которых меньше, чем указано в переменной ft_min_word_len

AS
На сайте с 12.12.2017
Offline
6
#6

https://stackoverflow.com/questions/14776350/mysql-like-operator-vs-match-against

Да отличается. Там(stackoverflow) рекомендуют вместо % использовать *

Вот так

AND MATCH (t1.name) AGAINST ('-*и*' IN BOOLEAN MODE)

Но что-то мне кажется что с этими изменениями запрос снова будет дольше выполняться.

D
На сайте с 28.06.2008
Offline
1114
#7

Кстати - из последнего измененного запроса можно убрать

UNION (SELECT 1 AS level, t1.*,
CONCAT_WS('-', t1.id, t1.alias) AS item_alias,
CONCAT_WS('-', t2.id, t2.alias) AS section_alias
FROM 13_cons_items AS t1
INNER JOIN 13_cons_sections AS t2 ON t1.section_id = t2.id
WHERE t1.parent_id = 0 AND t1.status = 1 AND t1.id != '13069' AND t1.section_id = '17'
AND MATCH (t1.name) AGAINST ('-Аномалия' IN BOOLEAN MODE)
AND MATCH (t1.name) AGAINST ('-Арнольда' IN BOOLEAN MODE)
AND MATCH (t1.name) AGAINST ('-Киари' IN BOOLEAN MODE)
AND MATCH (t1.name) AGAINST ('-ст' IN BOOLEAN MODE)
AND MATCH (t1.name) AGAINST ('-и' IN BOOLEAN MODE)
AND MATCH (t1.name) AGAINST ('-Аспаркам' IN BOOLEAN MODE))

рузультат остается тот же

---------- Добавлено 30.12.2017 в 10:38 ----------

AutoSearches:
AND MATCH (t1.name) AGAINST ('-*и*' IN BOOLEAN MODE)

Звездочки ничего не изменили

[umka]
На сайте с 25.05.2008
Offline
456
#8
Dram:

рузультат остается тот же

https://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html

Note: The - operator acts only to exclude rows that are otherwise matched by other search terms. Thus, a boolean-mode search that contains only terms preceded by - returns an empty result. It does not return “all rows except those containing any of the excluded terms.”

Оператор "-" не работает отдельно. Делайте как написано в посте #3

AS
На сайте с 12.12.2017
Offline
6
#9

А попробуйте такой вариант:


(SELECT 0 AS level, t1.*,
CONCAT_WS('-', t1.id, t1.alias) AS item_alias,
CONCAT_WS('-', t2.id, t2.alias) AS section_alias
FROM 13_cons_items AS t1
INNER JOIN 13_cons_sections AS t2 ON t1.section_id = t2.id
WHERE t1.parent_id = 0 AND t1.status = 1 AND t1.id != '13069' AND t1.section_id = '17'
AND MATCH(t1.name) AGAINST ('*Аномалия* *Арнольда* *Киари* *ст* *и* *Аспаркам*' IN BOOLEAN MODE)
UNION (SELECT 1 AS level, t1.*,
CONCAT_WS('-', t1.id, t1.alias) AS item_alias,
CONCAT_WS('-', t2.id, t2.alias) AS section_alias
FROM 13_cons_items AS t1
INNER JOIN 13_cons_sections AS t2 ON t1.section_id = t2.id
WHERE t1.parent_id = 0 AND t1.status = 1 AND t1.id != '13069' AND t1.section_id = '17'
AND MATCH(t1.name) AGAINST ('-*Аномалия* -*Арнольда* -*Киари* -*ст* -*и* -*Аспаркам*' IN BOOLEAN MODE))
ORDER BY level ASC LIMIT 3
D
На сайте с 28.06.2008
Offline
1114
#10
'[umka:
;15411213']match … against как минимум не учитывает "ст" и "и", и любые слова, длина которых меньше, чем указано в переменной ft_min_word_len

Вы правы, если из изначального запроса выкинуть

LIKE '%ст%' OR t1.name
LIKE '%и%' OR t1.name

то получается результат второго запроса

---------- Добавлено 30.12.2017 в 12:16 ----------

AutoSearches:
А попробуйте такой вариант:

попробовал, к сожалению

*ст* *и*

не учитываются по ходу

---------- Добавлено 30.12.2017 в 12:17 ----------

Но результат выборки тоже вполне годится! так что всем спасибо - главное запрос ускорен!

---------- Добавлено 30.12.2017 в 13:34 ----------

Все оказлось несколько сложнее чем думал.... эти кавычки в пхп съедят мой мозХ

Как перевести

$sql[] = "t1.name LIKE ".$this->_db->quote('%'.$word.'%');
$sql2[] = "t1.name NOT LIKE ".$this->_db->quote('%'.$word.'%');

в AGAINST?

пробую так

$sql[] = "MATCH(t1.name) AGAINST ".$this->_db->quote(''.$word.'');
$sql2[] = "MATCH(t1.name) AGAINST ".$this->_db->quote(''.$word.'');

получаю

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax

---------- Добавлено 30.12.2017 в 13:37 ----------

так тоже ошибка

$sql[] = "MATCH(t1.name) AGAINST ".$this->_db->quote('(*'.$word.'*)');
$sql2[] = "MATCH(t1.name) AGAINST ".$this->_db->quote('(-*'.$word.'*)');
12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий