$unset not working in node (Mongoose) while working in mongosh - javascript

how come wouldn't Mongoose and Mongosh return the same answer?
In the Schema, I have user ID and IoT device (smart light). Goal that I am trying to achieve is to remove completely first item in "smart_light" section.
Using Mongosh code works fine, but Mongoose is not removing the item. No errors are thrown, just "{acknowledged: false}". Mongoose is used with Node.
Schema (I am using replica set):
{
"UserID": "6276a2a6e59469e642801f4f",
"smart_light": {
"1": {
"Device_ID": "1",
"Device_Details": {
"Online_Status": true,
"DeviceManufacturer": "Philips",
"Model": "S-Li-7",
"Serial_Number": "302504-519574",
"Last_Update": {
"Date": "2014-05-11 19:59:37",
"Version": "V4",
"Update_Pending": false
},
"Communication_Protocol_Set": [
"Zigbee",
"Zwave"
],
"Spare_Parts": [
"Bridge"
]
},
"Device_Status": {
"Colour": "#08b8cd"
}
},
"2": {
"Device_ID": "2",
"Device_Details": {
"Online_Status": true,
"DeviceManufacturer": "Philips",
"Model": "S-Li-5",
"Serial_Number": "136985-212439",
"Last_Update": {
"Date": "2011-08-16 03:45:29",
"Version": "V2",
"Update_Pending": true
},
"Communication_Protocol_Set": [
"Zwave"
],
"Spare_Parts": [
"Bridge"
]
},
"Device_Status": {
"Colour": "#4bf14b"
}
}
}
}
Mongosh:
db.iot_customer_devices.updateOne(
{UserID: "6276a2a6e59469e642801f4f"},
{"$unset":{"smart_light.1":""}});
Mongoose:
IoT_Customer_Device.updateOne(
{UserID: "6276a2a6e59469e642801f4f"},
{$unset: {"smart_light.1":""}},
{ safe: true, multi:true },
function(err, result) {
if (err) {
console.log(err);
} else {
console.log(result);
}}
);
===================================================================
Update1:
It seems that if I try to remove (with mongoose) "UserID", this works... But objects cannot be removed so far?
IoT_Customer_Device.findOneAndUpdate(
{ UserID: "6276a2a6e59469e642801f18" },
{$unset: {"UserID":1}}, (err, res) => {
console.log(res);
});

This is now closed, answer has been found:
IoT_Customer_Device.updateOne(
{ UserID: "6276a2a7e59469e642801f86" },
[
{ $unset: "smart_light.1" }
],
(err, data) => {
if (!err) {
res.redirect('/devices/smart_light');
}
else { console.log('Error in device delete :' + err); }
}
);
This is working as intended, found my inspiration here

Related

Loopback:TypeError: Cannot read property 'find' of undefined

I saw a few questions like mine but couldn't find any solutions that worked so I thought I'd ask.
I'm trying to pull all my data from my database so I can select parts of it in my app. I had my database working fine but when I tried to pull the pictures it failed and keeps giving me this error and also does not seem to receive the data from the database:
app.model.users.find((err,result)=>{
^
TypeError: Cannot read property 'find' of undefined
Here is my code:-
server.js:-
'use strict';
const loopback = require('loopback');
const boot = require('loopback-boot');
const app = module.exports = loopback();
app.start = function() {
// start the web server
return app.listen(function() {
app.emit('started');
const baseUrl = app.get('url').replace(/\/$/, '');
console.log('Web server listening at: %s', baseUrl);
if (app.get('loopback-component-explorer')) {
const explorerPath = app.get('loopback-component-explorer').mountPath;
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
}
});
};
// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(app, __dirname, function(err) {
if (err) throw err;
// start the server if `$ node server.js`
if (require.main === module)
app.start();
});
console.log(Object.keys(app.models));
app.model.users.find((err,result)=>{
if(result.length ===0){
const user={
email:'jhanvi#gmail.com',
password:'jhanvi',
username: 'jhanvi',
};
app.models.user.create(user,(err,result)=>{
console.log("tried to create user ",err,result);
});
}
});
app.models.user.afterRemote('create', (ctx,user,next) =>{
console.log("new user is",user);
app.models.Profile.create({
first_name: user.username,
created_at: new Date(),
userId: user.id
},(err,result)=>{
if(!err && result){
console.log("created new profile",result);
}
else{
console.log("there is an error ",err);
}
});
next();
});
user.json:-
{
"name": "user",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"email": {
"type": "string"
},
"password": {
"type": "string"
}
},
"validations": [],
"relations": {
"Profile": {
"type": "hasMany",
"model": "Profile",
"foreignKey": ""
},
"accessTokens":{
"type":"hasMany",
"model":"CustomAccessToken",
"foreignKey":"userId"
}
},
"acls": [],
"methods": {}
}
Profile.json :-
{
"name": "Profile",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"created_at": {
"type": "date"
},
"age": {
"type": "number"
},
"history": {
"type": [
"object"
]
}
},
"validations": [],
"relations": {
"user": {
"type": "belongsTo",
"model": "user",
"foreignKey": "userId"
}
},
"acls": [],
"methods": {}
}
In your model you refer to user.
app.model.users.find((err,result)
should then surely be
app.model.user.find((err,result)
(i see you seem to be using both versions...)

mongo query from loopback issue

I am trying to query in mongo db from loopback model. But i am not getting any result from monogdb
This is how my document looks like in mongodb
{"_id":"5b9f8bc51fbd7f248cabe742",
"agentType":"Online-Shopping",
"projectId":"modroid-server",
"labels":["category","price"],
"phrases":["Look for _^ct_ in _^p_ ",
"I need _^ct_ in _^p_",
"can you search for _^ct_ in _^p_"]
}
here is my datasource file
{
"db": {
"name": "db",
"connector": "memory"
},
"modroid-server": {
"host": "localhost",
"port": 27017,
"url": "",
"database": "modroid-server",
"password": "",
"name": "modroid-server",
"user": "",
"connector": "mongodb"
}
}
and here is model-config file
{
"_meta": {
"sources": [
"loopback/common/models",
"loopback/server/models",
"../common/models",
"./models"
],
"mixins": [
"loopback/common/mixins",
"loopback/server/mixins",
"../common/mixins",
"./mixins"
]
},
"User": {
"dataSource": "db"
},
"AccessToken": {
"dataSource": "db",
"public": false
},
"ACL": {
"dataSource": "db",
"public": false
},
"RoleMapping": {
"dataSource": "db",
"public": false,
"options": {
"strictObjectIDCoercion": true
}
},
"Role": {
"dataSource": "db",
"public": false
},
"agent": {
"dataSource": "modroid-server", // here is my mongodb
"public": true
}
}
and here is my code to query in mongodb
module.exports = function (Agent) {
Agent.getDataSource().connector.connect(function (err, db) {
var collection = db.collection("text-responses");
collection.find({ "where": { "labels": ["category", "price"] } }, function (err, res) { // define whichever query you need
console.log("collection find res:"+res);
console.log("collection find err:"+err);
if(err) {
cb(err);
return;
}
res.toArray(function (err, realRes) { // this part is crucial
// otherwise if you try to print res you will get a dump of the db object
if(err) {
cb(err);
return;
}
console.log("documnet result:"+realRes);
console.log("document err:"+err);
})
})
}
);
}
and when i hit that rest api. I get this output
collection find res:[object Object]
collection find err:null
documnet result:
document err:null
please help me where i am doing thing wrong. I am stuck in that from couples of days.
Edited
when i just print res it gives me huge data which starts as
Cursor {
pool: null,
server: null,
disconnectHandler:
Store {
s: { storedOps: [], storeOptions: [Object], topology: [Object] },
length: [Getter] },
bson: BSON {},
ns: 'modroid-server.text-responses',
cmd:
{ find: 'modroid-server.text-responses',
limit: 0,
skip: 0,
query: { where: [Object] },
slaveOk: true,
readPreference: ReadPreference { mode: 'primary', tags: undefined } },
Look like text-responses is Not a model.
Try with Direct Model Agent.
module.exports = function (Model) {
Model.getDataSource().connector.connect(function (err, db) {
Model.find({ "where": { "labels": ["category", "price"] } }, function (err, res) { // define whichever query you need
console.log("collection find res:"+res);
console.log("collection find err:"+err);
})
});
}
Or
By collection
module.exports = function (Model) {
Model.getDataSource().connector.connect(function (err, db) {
var collection = db.collection("collection-name"); //use agent
collection.find({ "where": { "labels": ["category", "price"] } }, function (err, res) { // define whichever query you need
console.log("collection find res:"+res);
console.log("collection find err:"+err);
})
}
);
}

How to make a get request to retrieve the latest document of an index in the elasticsearch cluster?

I am developing a node.js application to get the latest value of an index from an elastic cluster. My logstash server pipes data to elasticsearch every second. So, the elasticsearch index gets updated every second. Every second a new document is added to the elasticsearch index.
Here is a sample JSON document
{
"_index": "weather",
"_type": "doc",
"_id": "eMIs_mQBol0Vk4cfUzG5",
"_version": 1,
"_score": null,
"_source": {
"weather": {
"main": "Clouds",
"icon": "04n",
"description": "broken clouds",
"id": 803
},
"#version": "1",
"clouds": {
"all": 75
},
"main": {
"humidity": 36,
"pressure": 1022,
"temp": 41,
"temp_max": 26,
"temp_min": 26
},
"wind": {
"deg": 360,
"speed": 3.6
},
"visibility": 16093,
"#timestamp": "2018-08-03T05:04:35.134Z",
"name": "Santa Clara"
},
"fields": {
"#timestamp": [
"2018-08-03T05:04:35.134Z"
]
},
"sort": [
1533272675134
]
}
Here is the picture of the table,
My node.js code looks like this,
let express = require('express');
let app = express();
let elasticsearch = require('elasticsearch');
app.get('/', function(req, res) {
res.send('Hello World!');
});
app.listen(3000, function() {
console.log('Example app listening on port 3000!');
});
let client = new elasticsearch.Client({
host: ['http://localhost:9200']
});
client.ping({
requestTimeout: 30000,
}, function(error) {
if (error) {
console.error('elasticsearch cluster is down!');
} else {
console.log('Everything is ok');
}
});
async function getResponse() {
const response = await client.get({
index: 'weather',
type: 'doc',
id: 'KsHW_GQBol0Vk4cfl2WY'
});
console.log(response);
}
getResponse();
I am able to retrieve the JSON document based on the id of the index. But, I want to retrieve the latest JSON document. How can I configure my server to read the latest document every second from the server? Is there a way to retrieve the latest JSON document(without knowing the id in advance)?
Can someone please help me with this? I would really appreciate if you could help.
Thanks in advance!
If you have a timestamp field in your index and that is updated/added after every document is indexed. Then you can simply perform a sort on timestamp field with size=1.
The below query will give you the most recent value:
{
"query": {
"match_all": {}
},
"size": 1,
"sort": [
{
"timestamp": {
"order": "desc"
}
}
]
}
Not sure of the syntax of node.js but something like this would work:
client.search({
index: 'weather',
type: 'doc'
body: {
sort: [{ "timestamp": { "order": "desc" } }],
size: 1,
query: { match_all: {}}
}
});
Based on your mapping you've #timestamp so you should use:
client.search({
index: 'weather',
type: 'doc'
body: {
sort: [{ "#timestamp": { "order": "desc" } }],
size: 1,
query: { match_all: {}}
}
});

Get back the whole JSON request from google action with Node js client library

I am using actions-on-goolge library for nodejs https://www.npmjs.com/package/actions-on-google
How would I able to get the whole JSON response, or use id string inside my intent function? I have tried to print out the input, it only gives the query part of the JSON. Tried to look up their documentation, it does not seem to explain how I could get back the whole JSON file.
https://developers.google.com/actions/reference/nodejs/lib-v1-migration
I am beginner of javascript.
The JSON request from simulator:
{
"user": {
"userId": "ABwppHEAPgcgb2yFUFURYFEJGg4VdAVcL9UKO9cS7a7rVfasdasdt67LzgrmMseTvb5mmJjbjj7UV",
"locale": "en-US",
"lastSeen": "2018-05-11T23:14:42Z",
"userStorage": "{\"data\":{}}"
},
"conversation": {
"conversationId": "1526080586367",
"type": "NEW"
},
"inputs": [
{
"intent": "com.example.device.OFF",
"rawInputs": [
{
"inputType": "KEYBOARD",
"query": "Talk to MyDevice to turn off"
}
],
"arguments": [
{
"name": "trigger_query",
"rawText": "turn off",
"textValue": "turn off"
}
]
}
],
"surface": {
"capabilities": [
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.WEB_BROWSER"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
},
"isInSandbox": true,
"availableSurfaces": [
{
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
}
]
}
My Node JS script base on the example:
const express = require('express')
const bodyParser = require('body-parser')
const {
actionssdk,
Image,
} = require('actions-on-google')
app.intent('actions.intent.TEXT', (conv, input) => {
if (input === 'bye' || input === 'goodbye') {
return conv.close('See you later!')
}
conv.ask(`I didn't understand. Can you tell me something else?`)
})
app.intent('com.example.MyDevice.TEST', (conv, input) => {
console.log(input);
console.log(conv.action);
console.log(conv.intent);
conv.close('Test Done');
});
express().use(bodyParser.json(), app).listen(3000)
You should be able to get the entire JSON request through conv.body.

Loopback embedsMany Helper methods don't work

I have these two models:
Student
{
"name": "student",
"plural": "students",
"base": "User",
"idInjection": false,
"options": {
"validateUpsert": true
},
"relations": {
"test": {
"type": "embedsMany",
"model": "test",
"property": "mytest",
"options": {
"validate": true,
"forceId": false
}
}
}
and
Test
{
"name": "test",
"base": "Model",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"text": {
"type": "string",
"required": true
}
}
}
When I try to create a new test I get this error
Error: Invalid reference: undefined
I create the test in this way:
Student.js
studentInstance.test.add({text : "something "})
What am I doing wrong?
Update
Delete in embedsMany
update id in test.
Student.js
Student.show = function(email, cb) {
Student.findById(email,function(err, student) {
...
var tmp = student.mytest;
for (var i = 0; i < tmp.length; i++) {
student.test.destroy(tmp[i].id);
}
})
...
}
I tried with
destroy not work correctly, not always remove the data
and
remove show this error
Error: Invalid reference: undefined
at EmbedsMany.remove
Update
Added a example of db
{
"_id": "value",
"property1": "value",
.
.
"mytest": [
{
"text": "something",
"creation": {
"$date": "2016-08-23T14:31:44.678Z"
},
"id": "d738253472876b17feb4b46b"
}
]
}
You don't have test model.
In test.json you defined its names as notification => "name": "notification",
UPDATE
For building (without persisting) an embedded instance please use studentInstance.test.build({text : "something "})
and for creating (with persisting) that please use studentInstance.test.create({text : "something "})
After 3 years, I've faced with same problem by using remove, destroyById.
And then I use unset method. It works.
Person.findById(body.metadata.person.id, (err, person) => {
person.creditCards.unset(
body.creditCard.id,
(err, res) => {
}
);
}
This works well.

Categories