MongoDB:对数组的高级查询

时间:2014-05-14 12:57:38

标签: php regex mongodb

假设我的集合中有以下对象:

{id:'123', tags:['berry', 'apple']}
{id:'456', tags:['salad', 'tomatoe']}
{id:'789', tags:['bread', 'rice']}

我的搜索字词是“草莓”。我想找到所有对象,其中一个标签是搜索词的一部分。在这种情况下,它是id为'123'的对象,因为'berry'是'Strawberry'的一部分。

我想使用Regex,就像这样(我正在使用php btw):

$regex = new MongoRegex("/.*berry.*/i");
$results = $mongodb->data->find(array("tags" => array('$in' => array($regex))));

但问题是正则表达式应用于标签而不是搜索结果。所以我需要反向正则表达式。

这样的查询是否有可能?现在我这样做:

$search = "Strawberry";
$js = "function() { var i = 0; for (; i < this.tags.length; i++) { if ('".$search."'.indexOf(this.tags[i]) != -1) { return true; } } }";
$results = $mongodb->data->find($js);

现在没关系,因为数据集不是很大,但将来会很慢。

有人有建议吗?感谢。

更新

很抱歉,如果仍然不清楚。 我的搜索条件是“草莓”,而不是“浆果”。我发布的包含正则表达式的PHP代码只是为了表明这不是一个解决方案而且不起作用。

再次:我的搜索词是“Strawberry”和我想找到所有对象,其中标签的一部分是搜索词的一部分,而不是相反

更新2:

为了更清楚,在SQL中这将是:

SELECT * FROM data WHERE 'Strawberry' LIKE CONCAT('%', tag, '%')

1 个答案:

答案 0 :(得分:0)

如果你有标签

,这个查询将匹配草莓
 db.collection.aggregate(
     [
       {$unwind: "$tags"}, 
       {$match : {tags: /.*berry.*/i  }}
     ]
    )

测试输出'

{
    "result" : [
            {
                    "_id" : ObjectId("537373c17c3639c32fe515fb"),
                    "id" : "123",
                    "tags" : "berry"
            },
            {
                    "_id" : ObjectId("537375337c3639c32fe515fe"),
                    "id" : "789",
                    "tags" : "strawberry"
            }
    ],
    "ok" : 1

}

就PHP而言,

$result = $mongodb->aggregate(array(
    array(
      '$unwind' => "$tags",
    ),
    array(
      '$match' => array(
          'tags' => /.*berry.*/i
      ),
    ),
));