如何匹配查询中包含一个或多个单词的行,但没有任何不在查询中的单词?
How to match rows with one or more words in query, but without any words not in query?
我在 MySQL 数据库中有一个 table,其中有一个逗号分隔的标签列表。
我希望用户能够输入逗号分隔的标签列表,然后使用 Sphinx 或 MySQL 到 select 行,其中至少有一个 查询中的标记,但查询中没有任何标记。
查询可以包含不在行中的其他标签,但如果行中包含不在查询中的标签,则不应匹配这些行。
我想使用 Sphinx 或 MySQL 进行搜索。
这是一个例子:
creatures:
----------------------------
| name | tags |
----------------------------
| cat | wily,hairy |
| dog | cute,hairy |
| fly | ugly |
| bear | grumpy,hungry |
----------------------------
示例搜索:
wily,hairy <-- should match cat
cute,hairy,happy <-- should match dog
happy,cute <-- no match (dog has hairy)
ugly,yuck,gross <-- should match fly
hairy <-- no match (dog has cute cat has wily)
grumpy <-- no match (bear has hungry)
grumpy,hungry <-- should match bear
wily,grumpy,hungry <-- should match bear
是否可以用 Sphinx 或 MySQL 做到这一点?
重申一下,查询将是一个逗号分隔的标签和行的列表,这些标签和行具有 至少一个输入的标签 但 没有任何标签查询没有 应该 selected。
Sphinx 表达式排序器应该可以做到这一点。
sphinxQL> SELECT *, WEIGHT() AS w FROM index
WHERE MATCH('@tags "cute hairy happy"/1') AND w > 0
OPTION ranker=expr('IF(word_count>=tags_len,1,0)');
基本上你希望匹配标签的数量永远不会少于标签的数量。
注意这些只是给所有文档的权重为 1,如果想获得更精细的排名(例如匹配其他关键字),它会变得更加复杂。
您需要在索引上启用 index_field_lengths
才能获得 tags_len 属性。
(相同的概念在 mysql 中显然是可能的。可能使用 FIND_IN_SET 进行匹配。或者使用第二列来存储数字,或者计算标签的数量,使用 say REPLACE 函数)
编辑添加,关于多个字段的详细信息...
sphinxQL> SELECT *, WEIGHT() AS w FROM index
WHERE MATCH('@tags "cute hairy happy"/1 @tags2 "one two thee"/1') AND w = 2
OPTION ranker=expr('SUM(IF(word_count>=IF(user_weight=2,tags2_len,tags_len),1,0))'),
field_weights=(tags=1,tags2=2);
SUM函数对每个字段依次运行,所以需要使用user_weight系统才能区分当前枚举的是哪个字段。
我在 MySQL 数据库中有一个 table,其中有一个逗号分隔的标签列表。
我希望用户能够输入逗号分隔的标签列表,然后使用 Sphinx 或 MySQL 到 select 行,其中至少有一个 查询中的标记,但查询中没有任何标记。
查询可以包含不在行中的其他标签,但如果行中包含不在查询中的标签,则不应匹配这些行。
我想使用 Sphinx 或 MySQL 进行搜索。
这是一个例子:
creatures:
----------------------------
| name | tags |
----------------------------
| cat | wily,hairy |
| dog | cute,hairy |
| fly | ugly |
| bear | grumpy,hungry |
----------------------------
示例搜索:
wily,hairy <-- should match cat
cute,hairy,happy <-- should match dog
happy,cute <-- no match (dog has hairy)
ugly,yuck,gross <-- should match fly
hairy <-- no match (dog has cute cat has wily)
grumpy <-- no match (bear has hungry)
grumpy,hungry <-- should match bear
wily,grumpy,hungry <-- should match bear
是否可以用 Sphinx 或 MySQL 做到这一点?
重申一下,查询将是一个逗号分隔的标签和行的列表,这些标签和行具有 至少一个输入的标签 但 没有任何标签查询没有 应该 selected。
Sphinx 表达式排序器应该可以做到这一点。
sphinxQL> SELECT *, WEIGHT() AS w FROM index
WHERE MATCH('@tags "cute hairy happy"/1') AND w > 0
OPTION ranker=expr('IF(word_count>=tags_len,1,0)');
基本上你希望匹配标签的数量永远不会少于标签的数量。
注意这些只是给所有文档的权重为 1,如果想获得更精细的排名(例如匹配其他关键字),它会变得更加复杂。
您需要在索引上启用 index_field_lengths
才能获得 tags_len 属性。
(相同的概念在 mysql 中显然是可能的。可能使用 FIND_IN_SET 进行匹配。或者使用第二列来存储数字,或者计算标签的数量,使用 say REPLACE 函数)
编辑添加,关于多个字段的详细信息...
sphinxQL> SELECT *, WEIGHT() AS w FROM index
WHERE MATCH('@tags "cute hairy happy"/1 @tags2 "one two thee"/1') AND w = 2
OPTION ranker=expr('SUM(IF(word_count>=IF(user_weight=2,tags2_len,tags_len),1,0))'),
field_weights=(tags=1,tags2=2);
SUM函数对每个字段依次运行,所以需要使用user_weight系统才能区分当前枚举的是哪个字段。