如何在MongoDB中使用$regex匹配字节类型数据?
MongoDB字节类型字段正则查询报错解决方法
问题场景
现有MongoDB文档如下:
{ 'name': 'demo', 'data': [ {'title': 'first', 'content': b'root'}, {'title': 'second', 'content': b'address mapping'}, ] }
使用Python Motor驱动执行针对字符串类型title字段的正则查询时可正常返回结果:
collection.find({'data.title': {'$regex': 'fir'}}, {'data.$': 1})
但执行针对字节类型content字段的正则查询时,抛出'$regex has to be a string'错误:
collection.find({'data.content': {'$regex': b'addr'}}, {'data.$': 1})
解决方案
MongoDB的$regex操作符仅支持字符串类型的正则参数,无法直接匹配字节字段,可通过以下两种方式解决:
1. 字节转字符串后匹配(适用于可解码为文本的字节内容)
通过聚合管道将字节类型的content字段转换为字符串,再使用$regexMatch进行正则匹配,同时用$filter筛选数组中符合条件的元素:
pipeline = [ { "$addFields": { "filtered_data": { "$filter": { "input": "$data", "as": "item", "cond": { "$regexMatch": { "input": {"$convert": {"input": "$$item.content", "to": "string", "onError": "", "onNull": ""}}, "regex": "addr" } } } } } }, {"$match": {"filtered_data": {"$ne": []}}}, {"$project": {"data": "$filtered_data", "_id": 0}} ] async for doc in collection.aggregate(pipeline): print(doc)
2. 字节级片段匹配(适用于不可解码为文本的字节内容)
如果字节内容无法解码为字符串,可使用$substrBytes提取指定长度的字节片段,再与目标字节序列进行精确匹配:
pipeline = [ { "$addFields": { "filtered_data": { "$filter": { "input": "$data", "as": "item", "cond": { "$eq": [ {"$substrBytes": ["$$item.content", 0, 4]}, b"addr" ] } } } } }, {"$match": {"filtered_data": {"$ne": []}}}, {"$project": {"data": "$filtered_data", "_id": 0}} ] async for doc in collection.aggregate(pipeline): print(doc)
原因说明
MongoDB的$regex是为字符串类型字段设计的查询操作符,不支持传入字节类型的正则表达式参数,因此直接在find方法中使用b'addr'作为$regex的值会触发错误。必须通过聚合管道的字段转换或字节级比较逻辑来实现对字节类型字段的匹配需求。
内容的提问来源于stack exchange,提问作者qiudeliang
相关产品推荐
相关产品推荐

