Currently working on a NodeJS backend with mongoDB. I'm trying to update an Object in mongoDB using NodeJS driver:
"mongodb": "^3.0.2",
I am using the findOneAndUpdate query and have tried the following syntax:
First syntax:
updatedPlayerData = await db.db(MDBC.db).collection(MDBC.pC).findOneAndUpdate({
'username': req.body.username
}, {
$set: {
[profession.city]: '',
[profession.organisation]: '',
[profession.profession]: ''
}
}, { returnOriginal: false });
Second syntax:
updatedPlayerData = await db.db(MDBC.db).collection(MDBC.pC).findOneAndUpdate({
'username': req.body.username
}, {
$set: {
profession: {
city: '',
organisation: '',
profession: ''
}
}
}, { returnOriginal: false });
Also have tried a bunch of other stuff. Can't seem to update the object properly. How can I properly update an object?
You can try this :
db.db(MDBC.db).collection(MDBC.pC).findOneAndUpdate({
'username': req.body.username
}, {
$set: {
'profession.city': '',
'profession.organisation': '',
'profession.profession': ''
}
}, { returnOriginal: false });
Related
This is my query:
await Users.updateOne(
{ _id: user._id },
{
$set: {
'email.isVerified': false,
'email.current': null,
},
$push: {
'email.oldEmails': {
email: "$email.current",
isVerified: "$email.isVerified"
},
},
}
);
The document has the fields email.current and email.isVerified but it cant use them in the $push pipeline. The query works fine otherwise but why cant I use the reference to the current document with "$.fiel" in the $push operation?
As far as i know there is no order in the update operators, and your update depends on order.If you want order you can use pipeline updates with aggregate operators/stages (MongoDB >= 4.2)
Its your query just as pipeline, and with $concatArrays instead of $push
(i haven't tested the code)
await Users.updateOne(
{ _id: user._id },
[
{
$set: {
'email.oldEmails':
{ $concatArrays: [ '$email.oldEmails',[{
email: "$email.current",
isVerified: "$email.isVerified"
}] ] }
'email.isVerified': false,
'email.current': null,
},
])
I use react 16.13 and am currently migrating from apollo-client 2.x to #apollo/client 3.1.1. I removed a lot of dependency libraries from my packages.json because most of them are now directly importable from #apollo/client. Everything was going fine until I tossed a big rock named "removal of defaults" while migrating from apollo-link-state.
With #apollo/client 3.x, we import InMemoryCache from #apollo/client directly, which is fine. But the withClientState link is no longer existent and ApolloClient doesn't support default values for local cache. I could not find any guide covering this problem. There is one guide for Angular, but it advises to use cache.writeData to construct the cache. Only problem is, in v3.x of #apollo/client, InMemoryCache doesn't have a writeData method anymore. There is a modify method but it is also not straightforward to use, at least I was not able to make it work for this purpose.
I have a large "defaults" object:
export default {
authentication: {
__typename: 'authentication',
auth: ''
},
UserInfo: {
__typename: 'UserInfo',
employee: {
__typename: 'UserInfoEmployee',
defaultShopId: '',
id: '',
email: '',
image: {
__typename: 'image',
id: '',
url: ''
},
firstName: '',
lastName: '',
manager: '',
boss: ''
},
countryCode: '',
chainId: ''
},
defaultShop: {
__typename: 'defaultShop',
id: '',
name: '',
timeZone: null
},
locale: {
__typename: 'locale',
locale: getBrowserLocale()
},
countries: {
__typename: 'countries',
data: []
},
Products: {
__typename: 'Products',
guid: 0,
ProductTypes: {
__typename: 'ProductTypes',
TypeNumber: 0,
type: ''
},
legacyConfiguration: false,
version: '1.0.0'
},
location: {
__typename: 'location',
pathname: '',
search: '',
hash: null,
action: '',
key: null,
isQueryActive: false,
query: null
}
}
How should I write these default data into InMemoryCache without using cache.writeData?
Use writeQuery instead.
I believe in v3 they moved towards using a common way for setting a default state.
Official docs
const query = gql`
query {
authentication #client {
id
__typename
}
...
}`
cache.writeQuery({
query,
data: {
authentication: {
__typename: 'authentication'
...
}
})
it needs to be written using policies, cache.writeQuery didn't work for me at the time of initialization,
cache.policies.addTypePolicies({
Query: {
fields: {
selectedCurrency: {
read() {
return "USD";
},
},
selectedIndex: {
read() {
return 0;
},
},
bookingFlowStep: {
read() {
return '';
},
},
},
},
});
I have two Sequelize models that are associated with a belongsTo relationship. I would like to create an instance of user_sources when user is created but I am struggling to accomplish it.
model_user:
const User = sequelize.define('user', {
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
},
password: {
type: Sequelize.STRING,
allowNull: false
}
}, {
tableName: 'users'
})
model_user_sources:
const UserSources = sequelize.define('user_sources', {
abcNews: {
type: Sequelize.BOOLEAN,
},
bbcNews: {
type: Sequelize.BOOLEAN,
}
}, {
tableName: 'user_sources'
})
UserSources.belongsTo(User)
Both models are initialized and the tables are created in the database properly. According to the Sequelize documentation I should be able to create both with association in a single query like so:
User
.create({
email: user.email,
password: user.password,
}, {
include: UserSources
})
However, only the user is created. The user_sources item does not get created in the table.
Unfortunately the documentation only shows an example of creating a parent model from a child model but not the other way around. I have tried several different methods such as using a hasOne association, adding model/association options into the include, putting data into the create method, etc. But I feel as though I am not grasping the concept properly.
Would appreciate if someone could shed some light on my problem. Thanks.
"sequelize": "^5.21.3". Here are three ways to create data records for User and UserSources model with associations. Besides, we keep adding the foreign key constraint using userId to user_sources table.
E.g.
index.js:
import { sequelize } from '../../db';
import Sequelize from 'sequelize';
const User = sequelize.define(
'user',
{
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
},
password: {
type: Sequelize.STRING,
allowNull: false,
},
},
{
tableName: 'users',
},
);
const UserSources = sequelize.define(
'user_source',
{
abcNews: {
type: Sequelize.BOOLEAN,
},
bbcNews: {
type: Sequelize.BOOLEAN,
},
},
{
tableName: 'user_sources',
},
);
UserSources.belongsTo(User);
// User.UserSources = User.hasOne(UserSources);
// User.hasOne(UserSources);
(async function test() {
try {
await sequelize.sync({ force: true });
// 1. User.UserSources = User.hasOne(UserSources);
// await User.create(
// {
// email: 'example#gmail.com',
// password: '123',
// user_source: {
// abcNews: true,
// bbcNews: true,
// },
// },
// {
// include: [
// {
// association: User.UserSources,
// },
// ],
// },
// );
// 2. User.hasOne(UserSources);
// await User.create(
// {
// email: 'example#gmail.com',
// password: '123',
// user_source: {
// abcNews: true,
// bbcNews: true,
// },
// },
// {
// include: [UserSources],
// },
// );
// 3. UserSources.belongsTo(User);
await UserSources.create(
{
abcNews: true,
bbcNews: true,
user: {
email: 'example#gmail.com',
password: '123',
},
},
{
include: [User],
},
);
} catch (error) {
console.log(error);
} finally {
await sequelize.close();
}
})();
After executing the above code, check the data records in the database:
node-sequelize-examples=# select * from "users";
id | email | password
----+-------------------+----------
1 | example#gmail.com | 123
(1 row)
node-sequelize-examples=# select * from "user_sources";
id | abcNews | bbcNews | userId
----+---------+---------+--------
1 | t | t | 1
(1 row)
The data records are created as expected.
I am trying to make a query to find documents depending on another document in the same collection as below.
The first one finds the user and the second one finds the data by using that user data received. But I want to do it with one query like join in SQL
This is schema
var ConnectionSchema = new Schema({
socketId: {
type: String,
require: true
},
location: {
type: [Number],
index: '2dsphere'
},
user: { type: Schema.ObjectId, ref: "User" },
date: {
type: Date,
require: true,
default: new Date()
}
});
// queries
return mongoose.model("Connection").findOne({ user: userId }).populate("user").then(usr => {
return mongoose.model("Connection").find({
location: {
$near: {
$maxDistance: config.searchDistance,
$geometry: { type: Number, coordinates: usr.location }
}
},
user: { $ne: userId },
});
});
Is there any way to do that with a just single query?
Thanks.
yes there is a way you can do like this
return mongoose.model("Connection").findOne({ user: userId })
.populate("user" ,
match : {$and : [{location: {
$near: {
$maxDistance: config.searchDistance,
$geometry: { type: Number, coordinates: usr.location }
}
}},
{user: { $ne: userId }}]})
.then(usr => {
// perform your action
});
I have a collection with the following format:
[
{
firstname: 'Joe',
lastname: 'Blow',
emails: [
{
email: 'test#example.com',
valid: false
},
{
email: 'test2#example.com',
valid: false
}
],
password: 'abc123',
_id: 57017e173915101e0ad5d94a
},
{
firstname: 'Johnny',
lastname: 'Doe',
emails: [
{
email: 'test3#example.com',
valid: false
}
],
password: 'abc123',
_id: 57017e173915101e0ad5d87b
},
]
I am trying to find a user based on the emails.email field. Here is what I have so far:
db.collection('users').aggregate([
{$unwind: "$emails"},
{$group: {_id: "$_id",user_emails: { $push: "$emails.email" } } },
{$match: {'user_emails': { $in: ['test#example.com'] } } }
],
(error, result) => {
console.log(error);
console.log(result);
}
);
When I run this command in the mongo shell it seems to work; however when I run it in Node.js it prints null for the error and [] for the result.
What am I doing wrong? I am pretty new to MongoDB and just can't seem to figure this out.
Why do you want to unwind the entire emails? That will be a very expensive operation when your collection grows with tons of records.
The below query will return the user with the email test2#example.com. I think thats what you are looking for right?
db.email.find({emails :{$elemMatch:{email:"test2#example.com"}}})
I have re-written your code with slight changes.
var col = db.collection('collection');
if (col) {
col.aggregate([
{$unwind: "$emails"},
{$group: {_id: "$_id",user_emails: { $push: "$emails.email" } } },
{$match: {'user_emails': { $in: ['test#example.com'] } } }
], function(e, r){
if(e){
console.log(error);
}
console.log(r);
db.close();
});
}
It should work, provided you have establish connection and other requirements successfully. Provided your sample documents, it will emit:
[
{
_id: '57017e173915101e0ad5d94a',
user_emails: [
'test#example.com',
'test2#example.com'
]
}
]