跨多数据库创建MongoDB视图失败,咨询该操作是否可行
跨MongoDB数据库创建视图的可行性分析及解决方案
首先直接给结论:MongoDB 不支持直接跨数据库创建视图。视图的核心限制在于,viewOn参数只能指定当前数据库内的现有集合名称(字符串格式),无法直接引用其他数据库的集合,更不能传入find()返回的游标对象——这也是你原代码报错的主要原因。
为什么你的原查询无法运行?
你的代码里犯了两个关键错误:
viewOn参数接收的是当前库集合名称的字符串,但你传入的是db.getSiblingDB("database2").getCollection("User").find({})返回的游标对象,这不符合MongoDB视图的语法要求。- MongoDB视图的数据源必须是当前数据库内的集合,不允许直接跨库引用外部集合。
可行的替代方案
如果你需要实现跨库数据关联并复用查询逻辑,可以采用以下两种方式:
方案1:先导入外部库数据到当前库,再创建视图
先将目标数据库的集合数据导入到当前数据库,然后基于这个本地集合创建视图:
use database1 // 把database2的User集合数据导入到当前库的User_imported集合 db.getSiblingDB("database2").User.aggregate([{ $out: "User_imported" }]) // 基于本地的User_imported集合创建视图 db.runCommand({ "create": "VW_User", "viewOn": "User_imported", "pipeline": [ { "$lookup": { "localField": "loginName", "foreignField": "userList.loginName", "from": "Site", "as": "User&Site" }}, { "$unwind": "$User&Site" }, { "$unwind": "$User&Site.userList" }, { "$project": { "_id": 0, "userId": "$_id", "userRole": "$User&Site.userList.role", "siteId": "$User&Site.id", "active": "$active", "connectedAtTime": "$connectedAtTime", "lastMessageTime": "$lastMessageTime" }} ] })
注意:$out操作会覆盖当前库中同名集合的数据,如果需要增量更新,可以改用$merge操作。
方案2:直接使用跨库聚合查询(无需创建视图)
如果不需要持久化视图,直接通过聚合查询实现跨库关联即可,MongoDB 3.2+支持$lookup跨数据库查询:
use database1 // 直接从database2的User集合出发,关联当前库的Site集合 db.getSiblingDB("database2").User.aggregate([ { "$lookup": { "localField": "loginName", "foreignField": "userList.loginName", "from": "database1.Site", // 跨库格式:数据库名.集合名 "as": "User&Site" }}, { "$unwind": "$User&Site" }, { "$unwind": "$User&Site.userList" }, { "$project": { "_id": 0, "userId": "$_id", "userRole": "$User&Site.userList.role", "siteId": "$User&Site.id", "active": "$active", "connectedAtTime": "$connectedAtTime", "lastMessageTime": "$lastMessageTime" }} ])
这种方式无需创建视图,直接得到你需要的关联结果,适合不需要复用视图的场景。
内容的提问来源于stack exchange,提问作者trying...
相关产品推荐
相关产品推荐

