【问题标题】:fetching data from mongodb and find closest value从 mongodb 获取数据并找到最接近的值
【发布时间】:2020-02-27 14:43:02
【问题描述】:

我的代码如下所示:

const express = require('express');
const mongoose= require('mongoose');

const Schema = mongoose.Schema;

const ourDataSchema = new Schema ({
   rank : Number,
   totalPoints : Number
});

const rankTotalpoint = mongoose.model("rankTotalpoint", ourDataSchema);

    const ourData = [
     {rank :1, totalPoints  : 2000},
     {rank :2, totalPoints  : 1980},
     {rank :3, totalPoints  : 1940},
     {rank :4, totalPoints  : 1890},
     {rank :5, totalPoints  : 1830},
     {rank :6, totalPoints  : 1765}
];

rankTotalpoint.create(ourData, function (error) {
    console.log('saved!');
    if (error) {
        console.log(error)
    }
});
...

我有两个问题:

  1. 如何通过 totalPoint 获取 rank

    • 我试过find(),但没用,我想我用错了。
  2. 我从用户那里得到一个输入(数字),我想将数字与我们从数据库中获取的 totalPoint(如果存在)(如果存在)进行匹配并返回它rank,如果不存在确切的数字,我想将它与我们数据库中最接近的 totalPoint 进行匹配,并将排名作为响应返回。

请至少回答我的第一个问题!

非常感谢您的回答,伙计们, 我被卡住了!

【问题讨论】:

  • 您认为最接近的是什么...如果用户输入 1800 - 应该返回 1830 还是 1765?
  • 这个没关系,我只是希望它与我拥有的totalPoint匹配并返回相关排名
  • 我已经提供了一个答案 - 如果这是您要找的,请告诉我。
  • 非常感谢你,这正是我想要的!它在现场演示中完美运行,但是当我在我的项目中使用邮递员对其进行测试时,它没有返回任何内容,我在这里发布我的代码作为答案,请查看。感谢您的友好回答,我真的被卡住了:)
  • 请看我更新的答案。 (也在这里添加,以防人们看到这个线程而不是另一个)

标签: node.js mongodb mongoose find fetch


【解决方案1】:

这些是我获取用户输入的控制器文件代码 并将其传递给您发送给我的代码,我将它们放入我的模型文件中。

const express = require('express');

const model = require('../model/logic');

exports.index = (req, res, next) => {
    res.status(200).json({message : 'INSERT INPUTS HERE'});
    };


  exports.getUserData = (req, res, next) => {
     const literature = req.body.literature * 4;
     const arabic = req.body.arabic * 2;
     const religion = req.body.religion * 3;
     const english = req.body.english * 2;
     const math = req.body.math * 4;
     const physics = req.body.physics * 3;
     const chemistry = req.body.chemistry *2;
     const TOTALPOINT = literature + arabic + religion + english + math + physics + chemistry;

     let result = model.result(TOTALPOINT);
     res.status(200).json(result); 
  };

这是我的模型/逻辑文件,我将它们导入到上面的控制器中:

const express = require('express');
const mongoose= require('mongoose');

const Schema = mongoose.Schema;

const ourDataSchema = new Schema ({
   rank : Number,
   totalPoints : Number
});

const rankTotalpoint = mongoose.model("rankTotalpointData", ourDataSchema);

const ourData = [
     {rank : 1, totalPoints   : 2000},
     {rank : 2, totalPoints   : 1980},
     {rank: 3,  totalPoints   : 1940},
     {rank:4, totalPoints    : 1890},
     {rank :5, totalPoints   : 1830},
     {rank : 6, totalPoints  : 1765},
     {rank : 7, totalPoints  : 1600}
 ];


rankTotalpoint.create(ourData, function (error, data) {
    if (error) {
        console.log(error)
    }
    else {
        console.log('saved!');
    }
});


exports.result = function (param) {
    const finalResult = rankTotalpoint.aggregate([
        {
          $project: {
            diff: {
              $abs: {
                $subtract: [
                  param, // <<<----------------------- THIS IS THE USER SUPPLIED VALUE
                  "$totalPoints"
                ]
              }
            },
            doc: "$$ROOT"
          }
        },
        {
          $sort: {
            diff: 1
          }
        },
        {
          $limit: 1
        },
        {
          $project: {
            _id: 0,
            rank: "$doc.rank"
          }
        }
      ])
   return finalResult;
}

当我使用邮递员测试我的应用时,我会在其中收到以下响应:

{
    "_pipeline": [
        {
            "$project": {
                "diff": {
                    "$abs": {
                        "$subtract": [
                            16,
                            "$totalPoints"
                        ]
                    }
                },
                "doc": "$$ROOT"
            }
        },
        {
            "$sort": {
                "diff": 1
            }
        },
        {
            "$limit": 1
        },
        {
            "$project": {
                "_id": 0,
                "rank": "$doc.rank"
            }
        }
    ],
    "options": {}
}

【讨论】:

    【解决方案2】:

    问题 #1:

    要按总点数查找排名,您可以:

    您可以查看live demo here

    db.collection.find({
      totalPoints: 2000 // <<<------------------ The exact value you want to find
    },
    {
      _id: 0,
      rank: 1
    })
    

    问题 #2:

    要通过用户提供的 totalPoints 值查找 最接近的排名,您应该能够使用以下查询...

    您可以查看live demo here

    db.collection.aggregate([
      {
        $project: {
          diff: {
            $abs: {
              $subtract: [
                1800, // <<<----------------------- THIS IS THE USER SUPPLIED VALUE
                "$totalPoints"
              ]
            }
          },
          doc: "$$ROOT"
        }
      },
      {
        $sort: {
          diff: 1
        }
      },
      {
        $limit: 1
      },
      {
        $project: {
          _id: 0,
          rank: "$doc.rank"
        }
      }
    ])
    

    更新/最终答案:

    您的问题是因为 Mongoose 是基于 Promise/async 的。您没有在等待任何事情,因此您的代码返回了一个尚未由您的查询设置的变量..

    我正在使用 2 个文件进行测试:myMongoose.jsindex.js..

    // myMongoose.js
    
    // ** CODE THAT SAVES DATA TO DATABASE HAS BEEN REMOVED FOR BREVITY **
    
    require('dotenv').config();
    const mongoose = require('mongoose');
    
    const RankTotalpointSchema = new mongoose.Schema({
      rank: Number,
      totalPoints: Number
    });
    
    mongoose.set('useCreateIndex', true);
    
    const mongoConnection = mongoose.createConnection(process.env.MONGO_DB_STRING, {
      useUnifiedTopology: true,
      useNewUrlParser: true,
      useFindAndModify: false,
    });
    
    const RankTotalpoint = mongoConnection.model("RankTotalpoint", RankTotalpointSchema, 'Testing');
    
    /**
     * ~~~~~~ **** THIS HAS TO BE AN ASYNC FUNCTION **** ~~~~~~
     */
    exports.result = async function (param) {
      const finalresult = await RankTotalpoint.aggregate([{
          $project: {
            diff: {
              $abs: {
                $subtract: [
                  param, // <<<----------------------- THIS IS THE USER SUPPLIED VALUE 
                  "$totalPoints"
                ]
              }
            },
            doc: "$$ROOT"
          }
        },
        {
          $sort: {
            diff: 1
          }
        },
        {
          $limit: 1
        },
        {
          $project: {
            _id: 0,
            rank: "$doc.rank"
          }
        }
      ])
      return finalresult;
    };
    

    ...然后在index.js:

    // index.js
    
    const { result } = require('./myMongoose');
    
    // Use it like this:
    async function init() {
        try {
            const d = await result(1800);
            console.log(d);
        } catch (err) {
            console.error(err);
        }
    }
    
    init(); // -> [ { rank: 5 } ]
    
    // --------------------------------------------------------------------
    
    // ...or like this:
    (async () => {
        try {
            const d = await result(1800);
            console.log(d); // -> [ { rank: 5 } ]
        } catch (err) {
            console.error(err);
        }
    })()
    
    // --------------------------------------------------------------------
    
    // ...or like this:
    result(1800)
        .then(d => console.log(d)) // -> [ { rank: 5 } ]
        .catch(err => console.error(err))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-10
      • 2020-09-16
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2015-03-01
      • 2012-10-27
      相关资源
      最近更新 更多