извлечение данных из mongodb и поиск ближайшего значения - PullRequest
0 голосов
/ 27 февраля 2020

Мой код выглядит следующим образом:

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)
    }
});
...

У меня есть 2 вопроса:

  1. Как получить ранг по totalPoint ?

    • Я пытался find(), но это не сработало, я думаю, что я использую это неправильно.
  2. I ' Получая ввод (число) от пользователя, я хочу сопоставить число с totalPoint (если существует), которое мы извлекли из нашей базы данных , и вернуть его ранг , и если точное число не существует, я хочу сопоставить его с ближайшим totalPoint в нашей базе данных и вернуть ранг в качестве ответа.

Пожалуйста, ответьте, по крайней мере, на мой первый вопрос!

Высоко ценю ваши ответы, ребята, я воняю!

Ответы [ 2 ]

0 голосов
/ 27 февраля 2020

Это коды файлов моего контроллера, где я получаю пользовательский ввод и передаю его в код, который вы отправляете мне, и я помещаю их в файлы моей модели.

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); 
  };

И это мой файл модели / логи c, который я импортировал в контроллер выше:

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": {}
}
0 голосов
/ 27 февраля 2020

Вопрос № 1:

Чтобы найти ранг по его TotalPoint, вы можете сделать:

Вы можете проверить демо здесь

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

Вопрос № 2:

Найти Ближайший Оцените, согласно предоставленному пользователем значению totalPoints, вы сможете использовать следующий запрос ...

Вы можете посмотреть живую демонстрацию здесь

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"
    }
  }
])

ОБНОВЛЕНИЕ / ЗАКЛЮЧИТЕЛЬНЫЙ ОТВЕТ:

Ваша проблема в том, что Mon goose основан на обещании / асин c. Вы ничего не ожидаете, поэтому ваш код возвращает переменную, которая еще не была установлена ​​по вашему запросу ..

Я тестировал, используя 2 файла: myMongoose.js и index.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))
...