从 MS Access 连接到外部 mongodb

connect to an outside mongodb from MS Access

有一个类似的帖子,我喜欢那里的一个答案,使用 shell 的那个。但它似乎连接到 mongo.

的 运行 实例

在我的例子中,没有 运行 实例,Mongo 数据库在其他地方,我不知道如何使用这个脚本连接到它。 我想我需要一种方法来使用类似于下面的方法将连接字符串添加到外部 MongoDB。

How to connect Mongodb from Excel

这就是答案

The Shell Approach Pretty much anything that interfaces with the Command Line can be accessed with Shell.

这是一个连接到 运行 Mongo 数据库实例并将查询打印到即时 Window 的基本示例。您需要添加对 Windows 脚本主机对象模型的引用。

Private Sub Test()

    Dim wsh As New WshShell
    Dim proc As WshExec
    Dim line As String
    
    Set proc = wsh.Exec("mongo")
    
    With proc
        .StdIn.WriteLine "use test"
        .StdIn.WriteLine "db.restaurants.find({""address.zipcode"":""10075""})"
        .StdIn.WriteLine "quit()"
        
        Do While .Status = WshRunning
            line = .StdOut.ReadLine
            If line = "Type ""it"" for more" Then
                .StdIn.WriteLine "it"
            ElseIf line Like "{*" Then
                Debug.Print line
            End If
            DoEvents
        Loop
    End With
End Sub

然而,仅打印原始 JSON 字符串并不是很令人兴奋或有用。您可以编写自己的 JSON 解析器,但在本示例中,我们将使用 Tim Hall 的 VBA-JSON(您可以在 GitHub 上找到它)。

在撰写本文时,VBA-JSON 存在一个问题,在使用它解析从 MongoDB 返回的字符串时必须解决该问题。任何包含括号的值,例如"_id": ObjectId("..."),会抛出错误。一个快速而肮脏的解决方法是使用 RegEx 为解析器清理字符串。您需要参考 Microsoft VBScript Regular Expressions 5.5 库才能使用以下函数。

Private Function CleanString(str As String) As String

    Dim temp As String
    Dim rx As New RegExp
    
    With rx
        .IgnoreCase = True
        .Global = True
        
        .Pattern = "[a-z]*\(" ' Left
        temp = .Replace(str, "")
        .Pattern = "\)" ' Right
        temp = .Replace(temp, "")
    End With
    
    CleanString = temp
End Function

然后我们可以解析从 MongoDB 返回的 JSON 并将每个对象添加到集合中。访问值变得非常简单。

Private Sub Mongo()

    Dim wsh As New WshShell
    Dim proc As WshExec
    Dim line As String
    Dim response As New Collection
    Dim json As Object
    
    Set proc = wsh.Exec("mongo")
    
    With proc
        .StdIn.WriteLine "use test"
        .StdIn.WriteLine "db.restaurants.find({""address.zipcode"":""10075""})"
        .StdIn.WriteLine "quit()"
        
        Do While .Status = WshRunning
            line = .StdOut.ReadLine
            If line = "Type ""it"" for more" Then
                .StdIn.WriteLine "it"
            ElseIf line Like "{*" Then
                response.Add ParseJson(CleanString(line))
            End If
            DoEvents
        Loop
    End With
    
    For Each json In response
        Debug.Print json("name"), json("address")("street")
    Next
End Sub

... 将从 MongoDB 示例数据集生成以下输出。

Nectar Coffee Shop          Madison Avenue
Viand Cafe                  Madison Avenue
Don Filippo Restaurant      Lexington Avenue
Lusardi'S Restaurant        Second Avenue
Due                         Third Avenue
Lenox Hill Grill/Pizza      Lexington Avenue
Quatorze Bistro             East   79 Street
Luke'S Bar & Grill          Third Avenue
Starbucks Coffee            Lexington Avenue
New York Jr. League         East   80 Street
Doc Watsons                 2 Avenue
Serafina Fabulous Pizza     Madison Avenue
Canyon Road Grill           1 Avenue
Sushi Of Gari East          78 Street

陷阱

ReadLineWriteLine 是阻塞函数。 Exec打开的window无法隐藏。 上述两种方法的解决方法是使用双层方法,其中 VBA 使用 wsh.Run 调用隐藏脚本,然后运行 ​​Exec(以及任何其他代码与 proc 交互)。这种方法的缺点是必须将 StdIn(并且在某种程度上 StdOut)写入文件。

要连接到外部 MongoDB,只需调整 Windows Shell 调用以指向外部地址。根据 MongoDB docsmongo 本身默认为端口 27017 处的本地主机。对于远程主机,请调整这些默认值。

使用连接字符串:

Set proc = wsh.Exec("mongo ""mongodb://username:password@host:port/database""")

使用args

Set proc = wsh.Exec("mongo --host <server_or_ip_address>" _
                  & "      --port <port_number>" _
                  & "      --username <username>" _
                  & "      --password <password>")

以上需要在客户端机器上安装 mongo shell,即使本地没有设置数据库。此外,托管 MongoDB 的服务器计算机必须允许外部连接。阅读文档以获取设置和说明。