【问题标题】:Mongodb query problem, how to get the matching items of the $or operatorMongodb查询问题,如何获取$or运算符的匹配项
【发布时间】:2021-01-09 07:29:48
【问题描述】:

首先谢谢你。

MongoDB 版本:4.2.11

我有这样一条数据:

{
 "name":...,
 ...
 "administration" : [
    {"name":...,"job":...},
    {"name":...,"job":...}
  ],
 "shareholder" : [
    {"name":...,"proportion":...},
    {"name":...,"proportion":...},
  ]
}

我想通过正则表达式匹配一些指定的数据: 例如:

db.collection.aggregate([
  {"$match" : 
   {
     "$or" : 
     [
       {"name" : {"$regex": "Keyword"}}
       {"administration.name": {"$regex": "Keyword"}},
       {"shareholder.name": {"$regex": "Keyword"}},
     ]
   }
  },
])

我想在 $or 运算符成功匹配任何条件时设置一个标志,由自定义字段表示,例如:{"name" : {"$regex": "Keyword"}}成功时执行:

{"$project" : 
        {
            "_id":false,
            "name" : true,
            "__regex_type__" : "name"
        }
    },

{"administration.name" : {"$regex": "Keyword"}}成功时执行:"__regex_type__" : "administration.name"

我尝试这样做:

{"$project" : 
            {
                "_id":false,
                "name" : true,
                "__regex_type__" : 
                {
                   "$switch":
                        {
                            "branches":
                            [
                              {"case": {"$regexMatch":{"input":"$name","regex": "Keyword"}},"then" : "name"},
                              {"case": {"$regexMatch":{"input":"$administration.name","regex": "Keyword"}},"then" : "administration.name"},
                              {"case": {"$regexMatch":{"input":"$shareholder.name","regex": "Keyword"}},"then" : "shareholder.name"},
                            ],
                            "default" : "Other matches"
                        }
                }
            }
        },

但是$regexMatch无法匹配数组,我再次尝试使用$unwind,但是返回了很多数组成员的个数,不符合我的出发点。

我想在mongodb中实现这个sql语句和mysql一样的功能,像这样:

SELECT name,administration.name,shareholder.name,(
 CASE
 WHEN name REGEXP("Keyword") THEN "name"
 WHEN administration.name REGEXP("Keyword") THEN "administration.name"
 WHEN shareholder.name REGEXP("Keyword") THEN "shareholder.name"
 END
)AS __regex_type__ FROM db.mytable WHERE 
  name REGEXP("Keyword") OR
  shareholder.name REGEXP("Keyword") OR
  administration.name REGEXP("Keyword");

也许这种方法很愚蠢,但我没有更好的解决方案。

如果您有更好的解决方案,我将不胜感激!!! 谢谢!!!

【问题讨论】:

    标签: sql mongodb mongodb-query


    【解决方案1】:

    由于 $regexMatch 不处理数组,使用 $filter 过滤单个数组元素和 $regexMatch,然后使用 $size 查看有多少元素匹配。

    [{"$match"=>{"$or"=>[{"a"=>"test"}, {"arr.a"=>"test"}]}},
     {"$project"=>
       {"a"=>1,
        "arr"=>1,
        "src"=>
         {"$switch"=>
           {"branches"=>
             [{"case"=>{"$regexMatch"=>{"input"=>"$a", "regex"=>"test"}},
               "then"=>"a"},
              {"case"=>
                {"$gte"=>
                  [{"$size"=>
                     {"$filter"=>
                       {"input"=>"$arr.a",
                        "cond"=>
                         {"$regexMatch"=>{"input"=>"$$this", "regex"=>"test"}}}}},
                   1]},
               "then"=>"arr.a"}],
            "default"=>"def"}}}}]
    [{"_id"=>BSON::ObjectId('5ffb2df748966813f82f15ad'), "a"=>"test", "src"=>"a"},
     {"_id"=>BSON::ObjectId('5ffb2df748966813f82f15ae'),
      "arr"=>[{"a"=>"test"}],
      "src"=>"arr.a"}]
    

    【讨论】:

      猜你喜欢
      • 2017-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多