MongoDB如何提取URL列中去重后的域名?
解决方案:提取去重域名的MongoDB聚合查询
没问题,我来帮你搞定这个从MongoDB URL集合中提取去重域名的需求!要实现这个目标,我们可以利用MongoDB的聚合框架,结合正则匹配和分组操作来完成,下面是具体的实现步骤和代码:
核心思路
- 从每个完整URL中剥离出域名部分(也就是
http://xxx.com或https://xxx.com,不包含后续的路径) - 按提取出的域名进行分组,自动实现去重
- 将最终结果整理成你预期的数组格式
方法一:正则匹配(MongoDB 4.2+推荐)
MongoDB 4.2及以上版本支持$regexFind操作符,能更简洁精准地匹配域名部分。假设你的集合名为urls,存储URL的字段名为url,查询代码如下:
db.urls.aggregate([ // 第一步:从URL中提取域名 { $addFields: { domain: { $getField: { field: "match", input: { $regexFind: { input: "$url", regex: /^https?:\/\/[^\/]+/ // 匹配http/https开头,到第一个斜杠前的内容 } } } } } }, // 第二步:按域名分组,自动去重 { $group: { _id: "$domain" // 用域名作为分组ID,天然实现去重 // 可选:如果需要统计每个域名对应的URL数量,添加下面这行 // count: { $sum: 1 } } }, // 第三步:将分散的域名结果整理成数组 { $group: { _id: null, uniqueDomains: { $push: "$_id" } } }, // 第四步:只输出域名数组 { $project: { _id: 0, uniqueDomains: 1 } } ])
运行这个查询后,你会得到完全符合预期的结果:
{ "uniqueDomains": ["http://xy.com", "http://ab.com"] }
方法二:适配旧版本MongoDB(4.2以下)
如果你的MongoDB版本低于4.2,没有$regexFind支持,可以用字符串分割的方式来提取域名:
db.urls.aggregate([ // 分割URL,提取协议部分 { $addFields: { urlParts: { $split: ["$url", "//"] }, protocol: { $arrayElemAt: [{ $split: ["$url", "//"] }, 0] } } }, // 从分割后的内容中提取域名(去掉后续路径) { $addFields: { domainPart: { $arrayElemAt: [{ $split: [{ $arrayElemAt: ["$urlParts", 1] }, "/"] }, 0] } } }, // 拼接回完整的域名格式 { $addFields: { domain: { $concat: ["$protocol", "//", "$domainPart"] } } }, // 分组去重并整理成数组 { $group: { _id: "$domain" } }, { $group: { _id: null, uniqueDomains: { $push: "$_id" } } }, { $project: { _id: 0, uniqueDomains: 1 } } ])
这个方法通过多次分割字符串来提取域名,效果和正则方法一致,只是代码稍长一些,适合版本较低的MongoDB环境。
内容的提问来源于stack exchange,提问作者Manish Rawat
相关产品推荐
相关产品推荐

