如何在查询中匹配行与一个或多个单词,但没有任何单词不在查询中?

时间:2015-02-27 14:37:54

标签: sphinx

我在MySQL数据库中有一个表,其中包含逗号分隔标记列表。

我希望用户能够输入逗号分隔的标签列表,然后使用Sphinx或MySQL选择至少有一个查询中的一个标签的行,但< em>没有任何标签,查询没有。

查询可以包含不在行中的其他标记,但如果行不在查询中,则不应匹配行。

我要么使用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执行此操作?

重申一下,查询将是一个逗号分隔的标签和行列表,其中至少有一个输入的标签不是查询没有的任何标签< / em>应该被选中。

1 个答案:

答案 0 :(得分:2)

狮身人面像表情排名应该能够做到这一点。

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进行匹配。或者使用第二列来存储数字,或使用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系统来区分当前枚举的字段。