这个问题有一个小背景,因为它表面上太通用了:
最近我遇到了一个问题,我不得不将我推送到我的sphinxql查询中的属性值作为全文移动,因为该属性需要成为“OR”查询的一部分。
换句话说,我在做:
Select * from idx_test where MATCH('Terms') and name_id in (1,2,3)
当我尝试在属性中添加“OR”时,例如:
Select * from idx_test where MATCH('Terms') and name_id in (1,2,3) OR customer_id in (4,5,6)
失败,因为Sphinx 2. *在属性查询中不支持OR
。
我也无法简单地将名称和客户ID放入查询中:
Select * from idx_test where MATCH('Terms ((@(name_id) 1|2|3)|(@customer_id) 4|5|6))')
因为(据我所知)你不能将整数字段推入full_text搜索。
我的解决方案是将_text
附加的第二次id字段编入索引:
Select name_id, name_id as name_id_text
然后将其添加到字段列表中:
sql_attr_uint = name_id
sql_field_string = name_id_text
sql_attr_uint = customer_id
sql_field_string = customer_id_text
所以现在我可以将我的OR查询作为full_text:
Select * from idx_test where MATCH('Terms ((@(name_id_text) 1|2|3)|(@customer_id_text) 4|5|6))')
但是最近我发现article讨论了属性和全文搜索之间的权衡。结果是“它可能会降低与少数记录匹配的查询的性能”。这正是我的name_id / city_id查询所做的。在一个理想的世界里,我可以回到:
Select * from idx_test where MATCH('Terms') and name_id in (1,2,3) OR customer_id in (4,5,6)
如果Sphinx只允许属性之间的OR
,因为据我所知,一旦我的查询过滤到相对较低的#结果,我就可以使用属性vs更快的查询full_text。
因此,我的两部分问题是:
OR
添加到SphinxQL查询的属性部分?答案 0 :(得分:2)
在Sphinx分支中添加了OR过滤器(来自2.3分支) - Manticore,请参阅https://github.com/manticoresoftware/manticore/commit/76b04de04feb8a4db60d7309bf1e57114052e298
目前仅在属性之间,不支持MATCH和属性之间的OR。
答案 1 :(得分:1)
虽然是,但是在WHERE中不直接支持OR,仍然可以运行查询。你的
Select * from idx_test where MATCH('Terms') and name_id in (1,2,3) OR customer_id in (4,5,6)
示例可以写为
Select *, IN(name_id,1,2,3) + IN(customer_id,4,5,6) as filter
from idx_test where MATCH('Terms') and filter > 0
这有点麻烦,但应该有效。你仍然可以获得全文倒排索引的全部好处,因此性能非常糟糕。 fitler仅针对与术语匹配的文档执行。 (这可能看起来很疯狂,如果来自说mysql背景,但记得sphinxQL不是mysql:)
你没有得到短路(即,即使匹配name_id,仍然会运行customer_id过滤器),所以也许
Select *, IF(IN(name_id,1,2,3) OR IN(customer_id,4,5,6),1,0) as filter
from idx_test where MATCH('Terms') and filter =1
更好,if函数有一个OR运算符! (因为狮身人面像可能会短路,但不知道是否会发生短路)
(但也是的,如果'过滤器'具有高度选择性(匹配几行),那么包括在全文查询中可能是好的。因为它在处理中丢弃了早期的行。问题使用非选择性过滤器,它们是否有许多匹配的行,因此在文本查询处理期间需要处理长文档列表)