Home > OS >  I need Help to get a simple query for MongoDB (SQL-equivalent: "select speed from values")
I need Help to get a simple query for MongoDB (SQL-equivalent: "select speed from values")

Time:01-08

I need help to get a simple query for MongoDB (SQL-equivalent: "select speed from values"). But I can't find a solution for.

Node.js backend for Vue.js

// a Part of Init-function:
await collection.replaceOne({}, {
      speed: {
        value: 65,
        type: 2,
      },
      eightSpeed: {
        value: 0.0043,
        type: 2,
      },
      oSpeed: {
        value: 0.31,
        type: 2,
      },
      minusSpeed: {
        value: 2.42,
        type: 2,
      }
}
//...

Now I need the query like this: http://192.168.220.220:3000/settings/getValue/speed to get an object speed.

const express = require("express");
const mongodb = require("mongodb");
const SettingsRouter = new express.Router();

SettingsRouter.get("/getValue/:value", async function (req, res) {
  try {
    const val = req.params.value; // req.body.text;
    const select = {};
    select[`${val}.value`] = 1;
    console.log("settings.js:", "/getValue/:name", select);
    const collection = await loadMongoCollection();
   
    const value = await collection.findOne({},select)//.toArray();
    res.status(201).send(value);
  } catch (error) {
    res.status(500).send("Failed to connect Database");
    console.error("settings.js:", "/getValue/:name:", error);
  }
});

async function loadMongoCollection() {
  const dbUri = process.env.MONGODB_CONNSTRING || config.dbUri;
  const MongoDB = process.env.MONGODB_DB || config.db;
  try {
    const client = await mongodb.MongoClient.connect(dbUri, {
      useNewUrlParser: true,
    });
    const conn = client.db(MongoDB).collection("values");
    return conn;
  } catch (error) {
    console.error("settings.js:", "loadMongoCollection:", error);
  }
}

When I try it, I get all (not only the Speed Object) what I expected, or nothing. What I do wrong?

EDIT 2022.01.06: I try it to change my database:

data = {
    speed: {
      value: 65,
      type: 2,
    },//...
}
//...
 await collection.replaceOne({}, {values:data}, { upsert: true });

and then the querry....

 const select = {[`values.${val}.value`]:"1"};
 const where = {}; //{"values":val};

const value = await collection.find(where,select,).toArray();


But it will not work in rest... is there an issue in mongo package?

When I do it in when I do it in https://cloud.mongodb.com - it works

But my request get me all values....

Log shows:"'settings.js:', '/getValue/:name', { 'values.speed.value': '1' }" enter image description here

CodePudding user response:

In the screenshot you show the projection is values.speed.value, but in your endpoint you have:

const select = {};
select[`${val}.value`] = 1;

Which would evaluate to speed.value. To mimic what you have on the MongoDB console this should be:

const select = {};
select[`values.${val}.value`] = 1;

CodePudding user response:

So, I changed my Frondend (vue) to spred all Values. I maked some Helper Functions:


  • CheckForChangedObj
    • check two object for changes
  • updateObj
    • copy all data from object into another

export function CheckForChangedObj(targetObject, obj) {
  if (targetObject === typeof undefined || targetObject == {}) {
    return true
  }

  if (JSON.stringify(targetObject) !== JSON.stringify(obj)) {
    return true
  }

  return false
}


export function updateObj(targetObject, obj) {
  let keys = Object.keys(obj)

  for (let k in keys) {
    try {
      let key = keys[k]
 
      if (!targetObject.hasOwnProperty(key)) {
        //define target, if not exist
        targetObject[key] = {}
      }

      //Workaround for References
      if (obj[key].hasOwnProperty("__v_isRef")) {
   
        if (targetObject[key].hasOwnProperty("__v_isRef")) {
          targetObject[key].value = obj[key].value
        } else {
          targetObject[key] = obj[key].value
        }
      } else {
        //Source i a Norm Value
        //check for an Object inside, then go in...
        if ("object" === typeof obj[key] && !Array.isArray(obj[key])) {
          updateObj(targetObject[key], obj[key]) // recurse
        } else {
          //not else-if!!! __v_isRef: true
          if (targetObject[key].hasOwnProperty("__v_isRef")) {
            targetObject[key].value = obj[key]
          } else {
            targetObject[key] = obj[key]
          }
        }
      }
    } catch (error) {
      console.log(
        "key:",
        keys[k],
        "Error:",
        error
      )
    }
  }
}


Then spreading...

import {updateObj,CheckForChangedObj } from "../tools/tools"

beforeMount() {
     this.getAllValuesAPI()
    setInterval(() => {
      this.checkForChanges()
      // ml("TABLE", this.values)
    }, 10000)
  },

setup() {
let prevValues = {}
let values = {
      speed: {
        id:1,
        type: SettingType.Slider,
        value: ref(0)
      }
      //...
}

      function checkForChanges() {
        //intervaled function to get changes from API
          let changed = CheckForChangedObj(this.values, this.prevValues)
          if (changed) {
            updateObj(this.prevValues, this.values)
            setValuesToAPI()
          }
          else{
            getAllValuesFromAPI()
          }
      }

      async function  getAllValuesFromAPI() {
        //get ALL Settings-Data from API, and put them in values
        const res = await axios.get(`settings/getAll`)
        return  updateObj(this.values, res.data[0].values) u
      }
}


When you have a better solution, please help...

  •  Tags:  
  • Related