使用部分_id字符串查找mongodb文档 [英] Find a mongodb document using a partial _id string

查看:129
本文介绍了使用部分_id字符串查找mongodb文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to find either one or more documents in a collection that have a specific string in their _id field.

这是一个问题,因为_id字段是一个对象,而不是一个字符串,所以我不能正则表达式。

this is proving to be a problem since the _id field is an object and not a string so i cant just regex it.

例如让我说这些文件与这些_id:

for example lets say i have these documents with these _id:

54060b811e8e813c55000058 
54060e9e1e8e813c55000059
540738e082fa085e5f000015

,我想搜索00005,结果应该是

and i want to search for "00005" then the result should be

54060b811e8e813c55000058
54060e9e1e8e813c55000059

有没有完成这个?

我需要这个jquery数据表实现,它使用PHP的服务器端处理。

i need this for a jquery datatables implementaion which uses the server-side processing with php.

这意味着我需要添加一些代码的这一部分:如果(!empty($ input ['sSearch'])){
$ sSearch = $ input ['sSearch',则

this means i need to add something to this portion of the code:

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' )
            );
        }
    }
}

任何建议将被apriciated

any advice would be apriciated

更新:

感谢saj,似乎有可能使用一个$ _ where子句如下:

thanks to saj it seems it is possible to find items using a partial _id by using a $where clause something like this:

$where: "this._id.toString().match(/pattern/i)"

我尝试将这个添加到PHP代码中:

i tried adding this to the php code like this:

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)"' )
            );
        }
    }
}

然而现在每个查询返回所有记录,而不是只有被匹配的记录。

however now every query returns all records instead of only the ones that are suppsoed to match.

任何想法?

解决方案:

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

thanks to your help i have figured this out, in order to add an open search in the _id field i need to add a $where clause in the $or section of the query array.

specificaly在我的情况下,我使用以下代码:

specificaly in my situation i used the following code:

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/)";
}

感谢您的帮助:)

就性能而言,我同意这是错误的方式,我将确保在其中添加一个strid字段,以使性能更好,但现在至少我有一个工作的解决方案

as far as performance i agree this is the WRONG way to go and i will make sure to have an added strign field with the _id in it to make performance much better, but for now atleast i have a working solution to the problem.

推荐答案

$ regex 和MongoRegex(即在等式匹配中使用的BSON正则表达式类型)仅支持与字符串匹配,因此您无法直接使用ObjectId。

The $regex and MongoRegex (i.e. a BSON regex type used in an equality match) only support matching against strings, so you cannot use them directly with an ObjectId.

关于您最后的代码示例,您尝试使用 $其中在MongoRegex构造函数中:

Regarding your last code example, you attempted to use $where in a MongoRegex constructor:

$searchTermsAny[] = array(
    $dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
    '$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);

MongoRegex 的构造函数使用单个字符串(例如 / foo / i ),从中导出模式和标志。 $其中 旨在用作顶级查询运算符(不与任何字段名称相关联)。我不遵循你在做什么与 $ dataProps [$ i] ,但我们假设你正在构建一个 $其中查询以匹配ObjectId的字符串表示形式。查询文档将如下所示:

MongoRegex's constructor takes a single string (e.g. /foo/i), from which it derives the pattern and flags. $where is intended to be use as a top-level query operator (not associated with any field name). I don't follow what you're doing with $dataProps[$i], but let's suppose you were constructing a single $where query to match an ObjectId's string representation. The query document would look like the following:

{ $where: 'this._id.str.match(/00005/)' }

请注意,我正在访问 str 属性,而不是调用 toString()。那是因为 toString()实际上返回了ObjectId的shell表示。您可以通过检查shell中的来源来查看此信息:

Note that I'm accessing the str property here instead of invoking toString(). That's because toString() actually returns the shell representation of the ObjectId. You can see this by checking its source in the shell:

> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
    return "ObjectId(" + tojson(this.str) + ")";
}

另外,如果你只是检查一个子串是否存在于 _id 的十六进制表示形式,您可能需要使用 indexOf() (含!= -1 比较),而不是 match()与正则表达式。

Also, if you're simply checking if a substring exists in the _id's hex representation, you may want to use indexOf() (with a != -1 comparison) instead of match() with a regex.

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

That said, using $where is generally a bad idea if you're not combining it with additional query criteria that can use an index. This is because $where invokes the JavaScript interpreter for each document considered in the result set. If you combine it with other, more selective criteria, MongoDB can use an index and narrow down the documents that it needs to evaluate with $where; however, you're in for a bad time if you're using $where and scanning many documents or a table scan in the worst case.

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

You're probably better of creating a second field in each document that contains the hex string representation of the _id. Then, you can index that field and query for it using a regex. The non-anchored regex queries will still be a bit inefficient (see: regex index use in the docs), but this should still be much faster than using $where.

此解决方案(复制 _id 字符串)将会导致每个文档增加一些存储空间,但您可以决定额外的24-30字节(字符串有效负载和短字段名称)是微不足道的。

This solution (duplicating the _id string) will incur some added storage per document, but you may decide the additional 24-30 bytes (string payload and a short field name) is negligible.

这篇关于使用部分_id字符串查找mongodb文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆