Php 使用部分id字符串查找mongodb文档

Php 使用部分id字符串查找mongodb文档,php,regex,mongodb,datatables,Php,Regex,Mongodb,Datatables,我需要在集合中找到一个或多个在其_id字段中具有特定字符串的文档 事实证明这是一个问题,因为_id字段是一个对象而不是字符串,所以我不能只对它进行正则化 例如,假设我有这些带有以下_id的文档: 54060b811e8e813c55000058 54060e9e1e8e813c55000059 540738e082fa085e5f000015 我想搜索“00005”,结果应该是 54060b811e8e813c55000058 54060e9e1e8e813c55000059 有没有办法做

我需要在集合中找到一个或多个在其_id字段中具有特定字符串的文档

事实证明这是一个问题,因为_id字段是一个对象而不是字符串,所以我不能只对它进行正则化

例如,假设我有这些带有以下_id的文档:

54060b811e8e813c55000058 
54060e9e1e8e813c55000059
540738e082fa085e5f000015
我想搜索“00005”,结果应该是

54060b811e8e813c55000058
54060e9e1e8e813c55000059
有没有办法做到这一点

我需要这个jquery datatables实现,它使用php的服务器端处理

这意味着我需要在这部分代码中添加一些内容:

if ( !empty($input['sSearch']) ) {
    $sSearch = $input['sSearch'];

    for ( $i=0 ; $i < $iColumns ; $i++ ) {
        if ($input['bSearchable_'.$i] == 'true') {
            if ($input['bRegex'] == 'true') {
                $sRegex = str_replace('/', '\/', $sSearch);
            } else {
                $sRegex = preg_quote($sSearch, '/');
            }
            $searchTermsAny[] = array(
                $dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i' )
            );
        }
    }
}
我尝试将其添加到php代码中,如下所示:

$where: "this._id.toString().match(/pattern/i)"
if ( !empty($input['sSearch']) ) {
    $sSearch = $input['sSearch'];

    for ( $i=0 ; $i < $iColumns ; $i++ ) {
        if ($input['bSearchable_'.$i] == 'true') {
            if ($input['bRegex'] == 'true') {
                $sRegex = str_replace('/', '\/', $sSearch);
            } else {
                $sRegex = preg_quote($sSearch, '/');
            }
            $searchTermsAny[] = array(
                $dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
                '$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
            );
        }
    }
}
if(!empty($input['sSearch'])){
$sSearch=$input['sSearch'];
对于($i=0;$i<$iColumns;$i++){
if($input['bsearcable.'$i]=='true'){
if($input['bRegex']=='true'){
$sRegex=str\u replace(“/”、“\/”、$sSearch);
}否则{
$sRegex=preg_quote($sSearch,“/”);
}
$searchTermsAny[]=数组(
$dataProps[$i]=>新MongoRegex('/'.$sRegex.'/i',
“$where:”this._id.toString().match(/“.$sRegex./i)”)
);
}
}
}
但是,现在每个查询都返回所有记录,而不是仅返回支持匹配的记录

有什么想法吗

解决方案:

多亏了您的帮助,我已经解决了这个问题,为了在_id字段中添加一个打开的搜索,我需要在查询数组的$or部分添加一个$where子句

具体来说,在我的情况下,我使用了以下代码:

if ( !empty($input['sSearch']) ) {
    $sSearch = $input['sSearch'];

    for ( $i=0 ; $i < $iColumns ; $i++ ) {
        if ($input['bSearchable_'.$i] == 'true') {
            if ($input['bRegex'] == 'true') {
                $sRegex = str_replace('/', '\/', $sSearch);
            } else {
                $sRegex = preg_quote($sSearch, '/');
            }
            $searchTermsAny[] = array(
                $dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i')
            );
        }
    }

    // add this line for string search inside the _id field
    $searchTermsAny[]['$where'] = "this._id.str.match(/$sSearch/)";
}
if(!empty($input['sSearch'])){
$sSearch=$input['sSearch'];
对于($i=0;$i<$iColumns;$i++){
if($input['bsearcable.'$i]=='true'){
if($input['bRegex']=='true'){
$sRegex=str\u replace(“/”、“\/”、$sSearch);
}否则{
$sRegex=preg_quote($sSearch,“/”);
}
$searchTermsAny[]=数组(
$dataProps[$i]=>新的MongoRegex('/'.$sRegex.'/i')
);
}
}
//在_id字段中添加此行用于字符串搜索
$searchTermsAny['$where']=“this.\u id.str.match(/$sSearch/)”;
}
谢谢你的帮助:)

就性能而言,我同意这是错误的做法,我将确保添加一个带有_id的strign字段,以提高性能,但至少目前我有一个有效的解决方案。

和MongoRegex(即在相等匹配中使用的BSON regex类型)只支持对字符串进行匹配,因此,不能将它们直接用于ObjectId

关于上一个代码示例,您尝试在MongoRegex构造函数中使用
$where

$searchTermsAny[] = array(
    $dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
    '$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);
的构造函数采用单个字符串(例如,
/foo/i
),从中派生模式和标志。用作顶级查询运算符(不与任何字段名关联)。我不了解您使用
$dataProps[$I]
所做的操作,但假设您正在构造一个
$where
查询以匹配ObjectId的字符串表示形式。查询文档如下所示:

{ $where: 'this._id.str.match(/00005/)' }
请注意,我在这里访问的是
str
属性,而不是调用
toString()
。这是因为
toString()
实际上返回ObjectId的shell表示形式。您可以通过在shell中检查其源代码来查看:

> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
    return "ObjectId(" + tojson(this.str) + ")";
}
此外,如果您只是检查
\u id
的十六进制表示中是否存在子字符串,您可能希望使用(带有
!=-1
比较)而不是带有正则表达式的
匹配()


也就是说,如果不将
$where
与可以使用索引的其他查询条件结合使用,那么使用
$where通常是个坏主意。这是因为,
$where
为结果集中考虑的每个文档调用JavaScript解释器。如果您将其与其他更具选择性的标准相结合,MongoDB可以使用索引并缩小需要使用
$where
评估的文档范围;但是,如果您使用
$where
并在最坏的情况下扫描许多文档或表扫描,那么您的处境将很糟糕

您最好在每个文档中创建第二个字段,该字段包含
\u id
的十六进制字符串表示形式。然后,您可以索引该字段并使用正则表达式查询它。非锚定正则表达式查询仍然有点效率低下(请参阅:在文档中),但这应该比使用
$where
快得多


此解决方案(复制
\u id
字符串)将为每个文档增加一些存储空间,但您可能会认为额外的24-30字节(字符串有效负载和短字段名)可以忽略不计。

可能不知道php抱歉,这里有一个指向Java版本的链接这似乎是一种方式,但我在实现它时遇到了问题,我会更新我的问题,也许以前有人已经这么做了谢谢你深思熟虑的回答,它给了我找到我需要的解决方案所需要的东西