Mongo 多语言模糊匹配
记一次mongo聚合查询匹配时,需要模糊匹配多语言下的文本
mongo存储数据结构如下:
{
"_id": {
"$oid": "61c2e92057ee825fb31c8448"
},
"created": {
"$date": {
"$numberLong": "1640163616884"
}
},
"modified": {
"$date": {
"$numberLong": "1640163616884"
}
},
"material_id": "m10034",
"uid": {
"$numberLong": "992128"
},
"material_info": {
"en-US": {
"name": "size",
"introduction": "size"
},
"zh-CN": {
"name": "中文",
"introduction": "简介"
}
},
"upload_time": {
"$date": {
"$numberLong": "1640163616000"
}
},
"down_load_address": "",
"material_md5": "dsdscsdsad",
"file_size": 122,
"cover_photo_address": ""
}
查询条件:模糊匹配 material_info下所有语言版本的 name的文本
思路如下:
1,利用 $objectToArray 把material_info 这个object 对象转为 一个数组
2,利用 $unwind 把数组拆分一条条的数据
3,利用 $regex 模糊匹配 所有的数据中的 name的文本,找到符合的结果
查询语句如下:
[ {"$project":{"lang":{"$objectToArray":"$material_info"}, "material_id":1 }},{"$unwind":"$lang"}, {"$match":{"lang.v.name":{"$regex":"44"} }} ]
来分析一下每一步的结果:
1,利用 $objectToArray 把material_info 这个object 对象转为 一个数组,这一步主要是为了把object对象转换为数组,执行结果如下:
2,利用 $unwind 把数组拆分一条条的数据,这一步是为了把 lang 这个数组拆开了成单一的对象,这样就可以直接进行条件的匹配
3,利用 $regex 模糊匹配 所有的数据中的 name的文本,找到符合的结果,经过前面两步后,现在管道里面的数据列表已经是一条条拆分好的数据,可以直接进行过滤即可
总结:主要是把复杂的object对象(类似于map),拆分成一个个独立的对象列表(类似于把map转成一个list),然后再把 list 拆解开来,最后进行条件过滤即可
参考如下:
mongo官方文档:https://www.mongodb.com/docs/manual/reference/operator/aggregation/objectToArray/