架构是不是必须完全匹配才能返回任何内容? (猫鼬)

Posted

技术标签:

【中文标题】架构是不是必须完全匹配才能返回任何内容? (猫鼬)【英文标题】:Does the schema have to match completely to return anything? (mongoose)架构是否必须完全匹配才能返回任何内容? (猫鼬) 【发布时间】:2019-10-11 17:08:52 【问题描述】:

我有一个非常简单的后端服务器和客户端,希望显示来自 mongo db 的数据,在一个名为 test 的数据库中的一个名为 cards 的集合中有文档。 当我从这个文件运行正则表达式时,它会返回一个文档,但是当我通过后端的 api 搜索它时,它什么也没有,没有错误,只有控制台中的“true”和“data:”。

cconst mongoose = require("mongoose");
const express = require("express");
var cors = require("cors");
const bodyParser = require("body-parser");
const logger = require("morgan");
const Data = require("./data");
const Card = require("./card");

const API_PORT = 3001;
const app = express();
app.use(cors());
const router = express.Router();

    // this is our MongoDB database
    const dbRoute =
      "mongodb+srv://dbUser:PASSWORD@cluster0-jhfnc.mongodb.net/test?retryWrites=true";

    // connects our back end code with the database
    mongoose.connect(dbRoute,  useNewUrlParser: true );

    let db = mongoose.connection;

    db.once("open", () => console.log("connected to the database"));

    // checks if connection with the database is successful
    db.on("error", console.error.bind(console, "MongoDB connection error:"));

    // (optional) only made for logging and
    // bodyParser, parses the request body to be a readable json format
    app.use(bodyParser.urlencoded( extended: false ));
    app.use(bodyParser.json());
    app.use(logger("dev"));

    // this is our get method
    // this method fetches all available data in our database
    router.get("/getCardsByName/:cardName", (req, res) => 
      const  name  = req.params.cardName;
      Card.find( name:  $regex: ".*" + name + ".*"  , (err, cards) => 
        if (err) return res.json( success: false, error: err );
        console.log("data: " + cards);
        return res.json( success: true, cards: cards );
      );
    );

    // append /api for our http requests
    app.use("/api", router);

    // launch our backend into a port
    app.listen(API_PORT, () => console.log(`LISTENING ON PORT $API_PORT`));

客户端如下所示:

// /client/App.js
import React,  Component  from "react";
import axios from "axios";

class App extends Component 
  // initialize our state
  state = 
    cards: [],
    id: 0,
    message: null,
    intervalIsSet: false,
    idToDelete: null,
    idToUpdate: null,
    objectToUpdate: null,
    cardToSearch: null
  ;

  // when component mounts, first thing it does is fetch all existing data in our db
  // then we incorporate a polling logic so that we can easily see if our db has
  // changed and implement those changes into our UI
  componentDidMount() 
    //this.getDataFromDb();
    if (!this.state.intervalIsSet) 
      let interval = setInterval(this.getDataFromDb, 1000);
      this.setState( intervalIsSet: interval );
    
  

  // never let a process live forever
  // always kill a process everytime we are done using it
  componentWillUnmount() 
    if (this.state.intervalIsSet) 
      clearInterval(this.state.intervalIsSet);
      this.setState( intervalIsSet: null );
    
  

  getCardByCardName = card_name => 
    fetch(`http://localhost:3001/api/getCardsByName/$card_name`)
      .then(cards => cards.json())
      .then(res => this.setState( cards: res.cards ));
  ;

  render() 
    const  cards  = this.state;
    return (
      <div>
        <ul>
          cards.length <= 0
            ? "No Cards Found"
            : cards.map(card => (
                <li style= padding: "10px"  key=card.id>
                  <span style= color: "gray" > id: </span> card.id <br />
                  <span style= color: "gray" > data: </span>
                  card.name
                </li>
              ))
        </ul>
        <div style= padding: "10px" >
          <input
            type="text"
            style= width: "200px" 
            onChange=e => this.setState( cardToSearch: e.target.value )
            placeholder="Card name"
          />
          <button
            onClick=() => this.getCardByCardName(this.state.cardToSearch)
          >
            FIND
          </button>
        </div>
      </div>
    );
  


export default App;

架构看起来像这样:

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

// this will be our data base's data structure
const CardSchema = new Schema(
  
    _id: Schema.Types.ObjectId,
    armor: Number,
    artist: String,
    attack: Number,
    cardClass: String,
    classes: Array,
    collectible: Boolean,
    collectionText: String,
    cost: Number,
    dbfld: Number,
    durability: Number,
    elite: Boolean,
    entourage: Array,
    faction: String,
    flavor: String,
    health: Double,
    hideStats: Boolean,
    howToEarn: String,
    howToEarnGolden: String,
    id: String,
    mechanics: Array,
    multiClassGroup: String,
    name: String,
    overload: Number,
    playRequirements: Object,
    questReward: String,
    race: String,
    rarity: String,
    referencedTags: Array,
    set: String,
    spellDamage: Double,
    targettingArrowText: String,
    text: String,
    type: String
  ,
   timestamps: true 
);

// export the new Schema so we could modify it using Node.js
module.exports = mongoose.model("Card", CardSchema);

【问题讨论】:

【参考方案1】:

事实证明我错误地使用了解构。应该是:

router.get("/getCardsByName/:cardName", (req, res) => 
  **const name = req.params.cardName;**
  console.log(name);
  Card.find( name:  $regex: ".*" + name + ".*"  , (err, cards) => 
    if (err) return res.json( success: false, error: err );
    console.log("data: " + cards);
    return res.json( success: true, cards: cards );
  );
);

【讨论】:

以上是关于架构是不是必须完全匹配才能返回任何内容? (猫鼬)的主要内容,如果未能解决你的问题,请参考以下文章

数据库中的文档是不是必须与模式完全匹配才能填充查询的文档?

在猫鼬中匹配具有字符串值的数组?

在猫鼬中匹配具有字符串值的数组?

猫鼬保存卡住(从未调用过回调)

猫鼬聚合返回空结果[重复]

猫鼬聚合返回空结果[重复]