我正在使用mongodb构建一个基本的搜索引擎,我已经验证了基本的查询在mongo shell中工作。我不太明白如何将其转换为 PHP。
输入字符串中的空格表示"and"运算符,| 或管道字符表示"or"运算符。输入查询会发生变化,但可能是这些行(减去引号!
'o g|ra'
这相当于写:
(o&&g)||(ra)
基本的mongo查询(请注意,我并不是每次都试图翻译这个确切的查询,我需要它在$ands和$ors的数量方面具有灵活性)。已经对此进行了测试,它工作正常:
db.scores.find({$or:[{Title:/o/i, Title: /g/i},{Title:/ra/i}])
我在PHP中生成的代码是这样的:
if(strstr($textInput, '|') != FALSE)
{
foreach($orArray as $item)
{
$itemMod = explode( " " , $item);
array_push($stringArray, $itemMod);
}
$masterAndQueryStack = array();
foreach ($stringArray as $varg)
{
$multiAndQuerySet = array();
foreach ($varg as $obj)
{
$searchText = '/'. $obj .'/i';
$regexObj = new MongoRegex( $searchText ) ;
$singleQuery = array('Title' => $regexObj);
array_push($multiAndQuerySet , $singleQuery);
}
array_push($masterAndQueryStack , $multiAndQuerySet);
}
$orAndQueryStack = array('$or' => $masterAndQueryStack);
return $orAndQueryStack ;
}
这是 PHP 代码返回的查询,如您所见,和 术语已放入数组中。我看不到任何在不将它们推送到数组的情况下存储它们的方法,但是似乎 mongodb 的$or不喜欢接受数组,我只是不确定如何重新处理搜索算法来解决这个问题。
Array
(
[$or] => Array
(
[0] => Array
(
[0] => Array ( [Title] => MongoRegex Object ( [regex] => o [flags] => i ) )
[1] => Array ( [Title] => MongoRegex Object ( [regex] => g [flags] => i ) )
)
[1] => Array
(
[0] => Array ( [Title] => MongoRegex Object ( [regex] => ra [flags] => i ) )
)
)
)
为了进一步解释我的评论,我将告诉您有关$and运算符的信息: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24and
您可以在第一次制作$or中嵌套它:
Array
(
[$or] => Array
(
[0] => Array
(
[$and] => Array
(
[0] => Array ( [Title] => MongoRegex Object ( [regex] => o [flags] => i ) )
[1] => Array ( [Title] => MongoRegex Object ( [regex] => g [flags] => i ) )
)
)
[1] => Array
(
[Title] => MongoRegex Object ( [regex] => ra [flags] => i )
)
)
)
诸如此类。您还可以在正则表达式中执行$and查询,此处有关正则表达式语法的一些信息:http://www.regular-expressions.info/refadv.html
不确定您必须搜索哪种类型的数据库,但当前的方法存在一些重大限制:
- 不区分大小写的正则表达式匹配将导致完全索引扫描
- 您正在将多个正则表达式匹配与$or组合在一起(增加性能开销)
- 匹配结果没有相关性排序
如果您没有要搜索的大型数据集,上述所有警告都可能没问题。
一些性能更高的替代方案是:
- 使用标签索引或标记化搜索关键字(请参阅相关维基页面Mongo中的全文搜索)
- 使用功能更全的全文搜索产品(请参阅有关 SO:NoSQL 数据库中的全文搜索的相关讨论)