在Clojure Luminus web框架中配置MongoDB

3
我正在配置一个MongoDB数据库,但在Luminus项目中遇到了问题。根据lein模板,这应该是相当简单的:https://github.com/yogthos/luminus-template。输入lein new luminus <name> +mongodb将为您提供默认的mongoDB设置,即文件:src/app-name/db/core.clj。要运行服务器,请键入lein ring server,它应该会打开一个Web浏览器并将其默认指向localhost:3000
将显示默认的首页,对于我来说,它告诉我“需要配置MongoDB”。它告诉我可以在同一文件src/app-name/db/core.clj中进行配置。我尝试了许多不同的方法,但目前我正在尝试并且对我来说最有意义的是以下内容:
(defonce coll "collection-name")
(defonce db (let [uri "mongodb://127.0.0.1/db-name"
                  {:keys [conn db]} (mg/connect-via-uri uri)]
              db))

很遗憾,当我连接我的浏览器时,仍然收到相同的“需要配置MongoDB”的消息。我还尝试使用CURL和在我的应用程序中定义的各种HTTP路由来访问数据库,但都没有成功。不过奇怪的是,在REPL中可以工作。
编辑:为了更清楚地说明问题,这里是REPL中的示例:
clj-project-name.db.core> (get-replies 2)
["mew-mew" [1.0 "hello"]]

在我的代码中,我有以下这些部分:

 (ns clj-project-name.routes.home
  (:require [compojure.core :refer :all]
            [clj-project-name.layout :as layout]
            [clj-project-name.util :as util]
            [clj-project-name.db.core :as project-db]))

(defn get-replies [id] (mc/distinct db coll "replies" {:_id id}))
(GET "/user" [id] (user-page id))  ; defined in home-routes inside namespace clj-project-name.routes.home 
(defn user-page [& [id]]           ;defined inside namespace clj-project-name.routes.home
  (layout/render "user.html"
                 {:id id
                  :replies (projectl-db/get-replies id)}))

<h1>User {{id}}'s page</h1>           ; part of the HTML template
<p> <b>Replies:</b> {{replies}} </p>  

这是在浏览器中加载的页面:

显示调用mongodb失败的页面

我们可以看到,replies 列表为空,而在REPL中我们看到应该是 ["mew-mew" [1.0 "hello"]]

编辑:另一个奇怪的地方是,当我输入 lein ring server 并加载浏览器后,我可以在终端上看到来自 mongodb 的以下输出:

2014-12-02T21:16:57.941-0500 [initandlisten] connection accepted from 127.0.0.1:38854 #28 (5 connections now open).

还有什么其他方法可以连接到MongoDB?感谢您的帮助。

3个回答

5
我按照您的步骤使用Luminus模板创建了新的Luminus项目。我还研究了生成的代码并发现默认主页是100%的静态页面。因此,无论是否已经配置,它都会显示“需要MongoDB配置”。请参考以下内容:

(defn home-page []
  (layout/render
    "home.html" {:content (util/md->html "/md/docs.md")}))

换句话说,它只是将resources/public/md/docs.md渲染成.html并显示出来,始终是同一个html页面。
至于您的配置,非常好。
至于您的user.html页面,实际问题在于user-page路由中的id是字符串,而您的数据库中的_id是数字。因此,您正在调用(get-replies "2")而不是(get-replies 2)。尝试使用字符串化的_id,或者首先使用read-string函数Long/parseLong解析传入的id
(defn user-page [& [id]]
  (layout/render "user.html"
                 {:id id
                  :replies (-> id
                               Long/parseLong ; throws NumberFormatException
                               project-db/get-replies)}))

我建议使用字符串化的_id,因为这比将字符串解析成数字更容易且更安全。


1
也许是因为您在命名空间app-name.db.core中使用了defonce而不是def,导致这些变量(colldb)没有被重新加载。 尝试停止lein进程,然后使用以下命令重新启动:
lein do clean, ring server

完成这个后,考虑采用更进一步的 组件 工作流:

https://github.com/stuartsierra/component


很遗憾,这也不起作用... 我仍然没有连接到mongodb。 - CodeKingPlusPlus

1

你的应用程序有太多的移动部件,而且你提供给我们的这些移动部件太少了,因此我们无法明确确定是什么导致了你的问题。我们只能提供一般性的调试建议。

  1. 确保您的环境干净。关闭您的REPL、Web服务器,甚至可能关闭您的编辑器。按照顺序重新启动所有内容,并记住该顺序。
  2. 我在您的帖子中看到了一堆奇怪的代码,但我无法确定它们是来自您的代码库还是由于您将代码复制到问题中而产生的。什么是projectl-db?get-replies是否与user-page在同一个命名空间中?确保您没有在REPL中引用旧版本的get-replies定义。
  3. db命名空间中的东西是以什么顺序定义的?也许colldbget-replies的顺序有误并且静悄悄地失败了。
  4. 您说(get-replies)在REPL中起作用。那么user-page在REPL中会说些什么?
  5. 您说您看到了"MongoDB configuration is Required"消息,但我看不到它。这是来自ring服务器,在浏览器中显示还是在浏览器控制台中显示的?
  6. 当您将replies的当前值的定义切换为整数值时会发生什么?例如,在user-page内部,返回一个映射{:id id, :replies 5}而不是调用get-replies。这个答案将有助于缩小问题的范围。
  7. 您能否将user-page排除在外,并从您的get-routes返回一个字符串?一旦您拥有了它,如果您返回get-replies(同样不使用user-page),会发生什么?
这里的原则,和所有调试一样,是将问题缩小到最少数量的部件,以重现问题。现在你有很多可能成为问题的部件,而且你只向我们展示了它们的一瞥。通过移除元素帮助自己,直到你找到导致该问题的最短的调用序列。寻求帮助或汇报错误时,请展示这个最小化的例子,这样他们不需要学习你的整个代码库。更重要的是,(你制作供人们进行调试的)代码的副本可能甚至没有该bug!
你还可以反向调试,从一个全新的工作库开始,逐个添加来自损坏库的部分,直到出现错误。当学习像Luminus这样的新框架的细节时,这会非常有帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接