四 数据获取

文章讲述了如何通过Railway平台连接MongoDB数据库,上传JSON数据,添加MongoDB的C++驱动,构建Docker镜像。接着介绍了如何查询MongoDB数据,使用Crow框架和Mustache模板引擎在网页中展示动态数据,以及如何根据电子邮件查询特定联系人信息。
摘要由CSDN通过智能技术生成

四. 数据获取

1. 连接mongo DB和service

  1. 登录railway,通过CLI和浏览器登录都可。
  2. 在dashboard - project,点击New添加MongoDB。
  3. 在service里添加variables:输入mongoDB,自动显示有关变量,添加MONGO_URL。
    附:railway自动添加username和password,无需手动创建。

2. 上传JSON数据

到MongoDB的网站,下载mongoDB工具
使用import 把contact.json导入数据库
切换到Exercise Files目录:

cd "/mnt/c/Users/Auly/Desktop/backend/Web_Servers_and_APIs_using_C++/Ex_Files_Web_Servers_APIs_C_PlusPlus/Exercise Files/Ch 04/04_02"

在railway - bashboard - mongo 可查看MONGO_URL,即uri选项。
把contacts.json引入mongodb:

mongoimport --authenticationDatabase admin --uri='mongodb://mongo:**********@containers-us-west-175.railway.app:7978' --collection='contacts' --jsonArray ./contacts.json

3. 添加MongoDB的C++ 驱动

为了访问mongoDB,需要把MongoDB的C++ drivers添加到代码中。
在hello_crow下新建bbox,在它下面添加如下Dockerfile,内容如下。

FROM  gcc:12.3

RUN apt-get -qq update
RUN apt-get -qq upgrade
RUN apt-get -qq install cmake

RUN apt-get install -y libboost-all-dev --no-install-recommends
RUN apt-get -qq install build-essential libtcmalloc-minimal4 && \ 
    ln -s /usr/lib/libtcmalloc_minimal.so.4 /usr/lib/libtcmalloc_minimal.so

WORKDIR /usr/src

RUN git clone https://github.com/mongodb/mongo-c-driver.git \
&& cd mongo-c-driver && git checkout 1.23.2 \
&& mkdir cmake-build && cd cmake-build \
&& cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF .. \
&& make && make install && ldconfig /usr/local/lib

RUN git clone https://github.com/mongodb/mongo-cxx-driver.git \
--branch releases/stable --depth 1 \
&& cd mongo-cxx-driver/build && cmake \
-DBSONCXX_POLY_USE_MNMLSTC=1 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DLIBMONGOC_DIR=/usr/lib/x86_64-linux-gnu \
-DLIBBSON_DIR=/usr/lib/x86_64-linux-gnu \
-DCMAKE_MODULE_PATH=/usr/src/mongo-cxx-driver-r3.7.0/cmake .. \
&& make EP_mnmlstc_core && make && make install && ldconfig /usr/local/lib

 它和第1个Dockerfile相似,前1-9行创建C++开发环境;
WORKDIR设置当前docker image的工作目录;
 第1个RUN git构建Mongo C驱动程序库,从github中获取源代码,用cmake构建make文件,构建并安装库,ldconfig告诉系统有关新库的消息;
 第2个RUN git构建Mongo C++驱动程序库,从github中获取源代码,执行cmake,选项传递包括-DBSONCXX_POLY_USE_MNMLSTC=1:把C++14及以上的功能带到C++11,-DCMAKE_BUILD_TYPE=Release:构建驱动程序的release版本,其余选项:构件中不同组件的位置。ldconfig告诉系统有关新库的消息。

 在bbox目录下,构建image:

docker build --rm --squash --no-cache -t bbox:latest .

注:1. 在vpn下使用该命令,若不,显示:

#0 20.03 E: Failed to fetch http://deb.debian.org/debian/pool/main/b/build-essential/build-essential_12.9_amd64.deb  502  Bad Gateway [IP: 146.75.114.132 80]
#0 20.03 E: Failed to fetch http://deb.debian.org/debian/pool/main/g/google-perftools/libtcmalloc-minimal4_2.8.1-1_amd64.deb  502  Bad Gateway [IP: 146.75.114.132 80]
#0 20.03 E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

若显示如下错误:

#0 9.602 E: Failed to fetch http://deb.debian.org/debian/pool/main/g/google-perftools/libtcmalloc-minimal4_2.8.1-1_amd64.deb  502  Bad Gateway [IP: 146.75.114.132 80]
#0 9.602 E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

是网络连接问题,切换线路或重试即可。
2. 版本问题:
第1个git中,注意git check out 后面的版本与gcc匹配,改新。

#0 14.60 CMake Error at src/bsoncxx/CMakeLists.txt:113 (find_package):
#0 14.60   Could not find a configuration file for package "libbson-1.0" that is
#0 14.60   compatible with requested version "1.13.0".
#0 14.60
#0 14.60   The following configuration files were considered but not accepted:
#0 14.60
#0 14.60     /usr/local/lib/cmake/libbson-1.0/libbson-1.0-config.cmake, version: 1.10.1

第2个git中,注意-DCMAKE_MODULE_PATH=/usr/src/mongo-cxx-driver-r3.7.0/cmake .. 中的版本改新。
警告不能使用squash,若使用squash,网页localhost:8080/contacts显示空白页。
可在bbox里手动建目录,cppweb/hell_crow。
或使用

docker build -t bbox:latest .

4. 查询Mongo数据

切换到hello_crow目录下,修改CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)

project(hello_crow)

set(CMAKE_CXX_STANDARD 11)
set(THREADS_PREFER_PTHREAD_FLAG ON)

find_package(Boost COMPONENTS system filesystem REQUIRED)
find_package(Threads REQUIRED)
find_package(libmongocxx REQUIRED)

add_executable(hello_crow main.cpp)
target_include_directories(hello_crow PRIVATE ${Boost_INCLUDE_DIRS} ${LIBMONGOCXX_INCLUDE_DIRS})
target_link_libraries(hello_crow ${Boost_LIBRARIES} Threads::Threads ${LIBMONGOCXX_LIBRARIES})

修改main.cpp,增加相关MongoDB C++ driver的头文件,增加处理contacts数据的路由:

// **************add****************
#include <fstream>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <boost/filesystem.hpp>

#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
#include <bsoncxx/oid.hpp>

#include <mongocxx/client.hpp>
#include <mongocxx/stdx.hpp>
#include <mongocxx/uri.hpp>
#include <mongocxx/instance.hpp>

using bsoncxx::builder::stream::close_array;
using bsoncxx::builder::stream::close_document;
using bsoncxx::builder::stream::document;
using bsoncxx::builder::stream::finalize;
using bsoncxx::builder::stream::open_array;
using bsoncxx::builder::stream::open_document;
using bsoncxx::builder::basic::kvp;
using mongocxx::cursor;
// **************add****************

int main(int argc, char* argv[]) 
{
    crow::SimpleApp app;
    // *****************add*********************
    mongocxx::instance inst{};
    string mongoConnect=std::string(getenv("MONGO_URL"));
    mongocxx::client conn{mongocxx::uri{mongoConnect}};
    auto collection=conn["test"]["contacts"];
    // ****************add***********************


    // *********add****************
    CROW_ROUTE(app, "/contacts")
    ([&collection]()
    {
        mongocxx::options::find opts;
        opts.limit(10);
        auto docs=collection.find({},opts);
        std::ostringstream os;
        for (auto&& doc :docs)
        {
                os<<bsoncxx::to_json(doc)<<endl;
        }
        return crow::response(os.str());
    });
    // ********add****************

    CROW_ROUTE(app, "/")
    ([](const crow::request& req, crow::response& res)
    {
        sendHtml(res, "index");
    });

}

* 注:因云平台的不同环境变量和数据库名称不同,main.cpp和docker命令随着改动。
在hello_crow目录下,修改里面的Dockerfile:

FROM bbox:latest

WORKDIR /usr/src/cppweb/hello_crow
COPY . .

WORKDIR /usr/src/cppweb/hello_crow/build
RUN cmake .
RUN make
CMD ["./hello_crow"]

在hello_crow目录下,构建image:

docker build -t hello_crow:latest .

打开端口:

docker run -p 8080:8080 -e PORT=8080 -e MONGO_URL="mongodb://mongo:3klH7rOKun3XOLnf3pHg@containers-us-west-175.railway.app:7978" hello_crow:latest

在浏览器输入:localhost880:contacts,显示mongdb collections里的数据。
在main.cpp,在CROW_ROUTE(app, "/contacts")增加跳过9行的选型:opts.skip(9),第10行变成了第1行。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-teoLxgAR-1685891597146)(/images/contacts_skip(9)].jpg)

5. 在页面中增加动态数据

(1) 使用mustache渲染

使用crow里的mustacle模板。
修改main.cpp,把contacts页面改好看,变成bulma风格表格形式。增加mustache命名空间,增加getView子函数,修改contacts路由:

// *************add**************
using namespace crow::mustache;
// *************add**************
// *************add**************
string getView(const string& filename, context& x)
{
    return load_unsafe(filename + ".html").render(x);
}
// *************add**************

int main(int argc, char* argv[]) 
{
    crow::SimpleApp app;
    // **************add******************
    crow::mustache::set_global_base("../public/");
    // **************add******************

    // ************modify**********
    CROW_ROUTE(app, "/contacts")
    ([&collection]()
    {
        mongocxx::options::find opts;
        opts.skip(9);
        opts.limit(10);
        auto docs=collection.find({}, opts);
        crow::json::wvalue dto;
        vector<crow::json::rvalue> contacts;
        contacts.reserve(10);

       for (auto&& doc : docs)
        {
                contacts.push_back(json::load(bsoncxx::to_json(doc)));
        }
        dto["contacts"] = contacts;
        return getView("contacts", dto);
    });
    // **********modify**********
    CROW_ROUTE(app, "/")
    ([](const crow::request& req, crow::response& res)
    {
        sendHtml(res, "index");
    });
}

*注:1. load显示空白页的话,用load_unsafe替代。
   2. 设置全局tmplate文件的目录,否则mustache不起作用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4CpKA6Dr-1685891597148)(images/contacts_table.jpg)]

(2) email查询

在网页中可通过email查询。修改main.cpp:
增加namespace,增加contact/<email>路由处理程序

// **************add***************
using bsoncxx::builder::basic::make_document;
// **************add***************
// **************add***************
   CROW_ROUTE(app, "/contact/<string>")
   ([&collection](string email)
   {
        auto doc=collection.find_one(make_document(kvp("email", email)));
        return crow::response(bsoncxx::to_json(doc.value().view()));
    });
// **************add***************

访问localhost:8080/contact/<email>(注意不是contacts)查询联系人的信息,显示:
在这里插入图片描述

在这里插入图片描述

6. 练习:用mongo 数据创建一个网页

  1. 在public下创建contact.html
  2. 用contact.html修改contact的路由
  3. 使用mustache渲染contact数据
  4. 页面使用bulma风格
    访问localhost:8080/contact/<email>(不是contacts)查询某个人的信息,显示:
    在这里插入图片描述

7. 解决方案

  1. 在public下创建contact.html
    在contacts.html的基础上修改:删除表格部分,增加联系人的图片。
    contact.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Contact</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
</head>
<body>
  <section class="section">
    <div class="content">
      <h1 class="title">Contact</h1>
          {{#contact}}
          <div>
            <p>{{firstName}} {{lastName}}</p>
            <p>{{email}}</p>
            <p>{{phone}}</p>
            <img src="{{photo}}" />
          </div>
          {{/contact}}
    </div>
  </section>
</body>
</html>
  1. 修改contact/<email>路由部分
   CROW_ROUTE(app, "/contact/<string>")
   ([&collection](string email)
   {
        auto doc=collection.find_one(make_document(kvp("email", email)));
        // crow::json::wvalue dto;
        crow::mustache::context dto;
        dto["contact"]=json::load(bsoncxx::to_json(doc.value().view())) ;
        return getView("contact", dto);;
    });
  1. 重新build hello_crow:latest image,打开端口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值