正则表达式作为投影中的$ filter

alf*_*ino 5 mongoose mongodb

我试图找到(使用正则表达式)一个数组字段并仅返回该元素

这是我的数据

  [
 {
"_id": "56d6e8bbf7404bd80a017edb",
"name": "document1",
"tags": [
  "A area1",
  "B area2",
  "C area3"
]
},
{
"_id": "56d6e8bbf7404bd82d017ede",
"name": "document2",
"tags": [
  "b_area3",
  "b_area4",
  "b_area5"
  ]
}
]
Run Code Online (Sandbox Code Playgroud)

我的查询

var query=new RegExp('^'+string, "i");

Model.find({tags:query},{'tags.$': 1}, function(err,data){
        if(err) console.log(err);
        res.json(data);
    });
Run Code Online (Sandbox Code Playgroud)

此查询仅选择标记字段(如我所愿),但选择第一个元素.我需要与查询匹配的元素.

编辑:我也尝试了mongodb聚合,$ filter cond是错误的.我收到错误"MongoError:invalid operator $ regex"

caseNote.aggregate([
    { $match: {tags:query}},
    { $project: {
        tags: {$filter: {
            input: 'tags',
            as: 'item',
            cond: {$regex: ['$$item', query]}
        }}
    }}
], function (err, result) {
    if (err) {
        console.log(err);
    } else {
        res.json(result);
    }
});
Run Code Online (Sandbox Code Playgroud)

EDIT2:关于@zangw的建议,这是mongoose版本,但它不完整:标签字段很好(需要测试),但查询仍然返回整个文档.

 caseNote
     .aggregate({ $match: {tags: {$in:['area3']}}})
     .unwind('tags')
     .exec(function(err,d){
         res.json(d);
     });
Run Code Online (Sandbox Code Playgroud)

tur*_*hal 7

根据@zangw的回答,

此ISSUE-SERVER-8892,根据此问题 Use $regex as the expression in a $cond,$regex 无法与当前 mongo 版本的 cond 一起使用。

MongoDB v4.1.11在ISSUE-SERVER-11947中推出了新功能,该功能在聚合语言中添加了三个新表达式$regexFind和。$regexFindAll$regexMatch

在您的示例中,您可以使用$regexMatch表达式,

Model.aggregate([
  {
    $project: {
      tags: {
        $filter: {
          input: "$tags",
          cond: {
            $regexMatch: {
              input: "$$this",
              regex: query
            }
          }
        }
      }
    }
  }
])
Run Code Online (Sandbox Code Playgroud)

操场


zan*_*ngw 6

根据这个问题Use $regex as the expression in a $cond,$regex不能cond用于当前的mongo版本.

也许你可以尝试这个,过滤area3通过$match,然后通过所有匹配的标签$group,然后删除_id通过$project.

caseNote.aggregate([{$unwind: '$tags'},
               {$match: {tags: /area3/}},
               {$group: {_id: null, tags: {$push: '$tags'}}},
               {$project: {tags: 1, _id: 0}}])
    .exec(function(err, tags) {
        if (err)
            console.log(err);
        else
            console.log(tags);
    });
Run Code Online (Sandbox Code Playgroud)

结果:

{ "tags" : [ "C area3", "b_area3" ] }
Run Code Online (Sandbox Code Playgroud)