Mongoose array query - javascript

I've been trying to query my database for a specific array element thats contained inside a user model, the schema looks a bit like this:
const schemaUser = new mongoose.Schema({
username: { type: String, required: true, unique: true },
email: {type: String, unique: true},
password: { type: String, required: true},
accounts: [{
id : String,
account_name : String,
name : String,
password : String,
description: String
}]
});
How could I go about selecting a specific account out of the "accounts" array using its custom id shown (not the Mongodb one) that is also contained inside a specific users object?
Cheers.

If you want to query for a record that contains a specific account depending on its id, you could use :
userSchema.findOne({ "accounts.id": { $eq: id }})

Since your question revolves around finding the user based on an array, rather than querying the mongoDB, you could use the array.find() method to return the object you want, based on the id property.
More about array.find() here.
Example:
const accountList = [
{
id : 1,
account_name : 'account_one',
name : 'John Doe',
password : 'asdhui"#¤7aysdg',
description: 'dummy account #1'
},
{
id : 2,
account_name : 'account_two',
name : 'Jane Doe',
password : 'asdhui"#¤7aysdg',
description: 'dummy account #2'
},
{
id : 3,
account_name : 'account_three',
name : 'Derrick Johnson',
password : 'asdhui"#¤7aysdg',
description: 'dummy account #3'
}
];
console.log(accountList.find(account => account.id === 1));
Note that the array.find() method will only return the first instance. If you want to do other types of lookups and return a list of users based on something that isn't unique, then you'd have to use the array.filter() method instead.
In the case you did mean to query the mongoDB, you could query for the field value of the specific document directly by specifying the field you want, followed by the $eq operator and value.
Example:
userSchema.findOne({ "id": { $eq: value } })
value being the specific id of the user you want.
More about the $eq operator here.

Related

Get an array of items from an object- typescript

I have an object with the below structure:
Order: [
{
id: '001',
type: '',
status: '',
users: [
{
OrderId:'001',
userId: 'String',
user: {
email: 'string',
givenName: 'Name',
lastName: 'LastName',
phone: 'string',
},
},
],
},
the order is of type Order[] and users of type UserData[]
type Order
#model
#key(fields: ["organizationId", "id"])
#auth(
rules: []
) {
id: ID!
type: OrderType
status: OrderStatus
userConnections: [UserOrderConnection] #connection(keyName: "byOrder", fields: ["id"])
organizationId: ID!
}
type UserOrderConnection
#model
#key(fields: ["organizationId", "id"])
#key(name: "Order", fields: ["OrderId"], queryField: "userOrderByOrder")
#auth(
rules: []
) {
id: ID!
accepted: Boolean
OrderId: ID!
Order: Order #connection(fields: ["organizationId", "id"])
userId: ID!
user: UserData
}
Whenever I try to get the list of users per order :
let users = this.Order.users
it says that: users don't exist on type Order[], can anyone explain for me why.
Order is an array of objects, you need to get the first element like Order[0] then access .users
let users = this.Order[0].users
A good refresher might help here; How can I access and process nested objects, arrays or JSON?
Order is an Array containing objects. To access users you would need to access item at index [0] if it has property ?.users.
this.Order[0]?.users

Is it possible to create nested objects with the same _id in mongoose?

As the title says.
For example this is my Schema:
var contactSchema = new mongoose.Schema ({
name: String,
surname: String,
address: String,
email: String,
addedNumbers: [
{ phone: String,
number: Number,
default: Boolean
}
]
});
Is it possible that all objects inside the addedNumbers array have the same _id as root?
_id mean "unique identifier" it should be unique.

MongoError: E11000 duplicate key error collection with passport

I have the following userSchema
var mongoose = require("mongoose"),
passportLocalMongoose = require("passport-local-mongoose");
var userSchema = new mongoose.Schema({
email: String,
password: String,
userName: String,
fname: String,
lname: String,
userType: Number,
subscribedThreads: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Threads"
}
]
});
// add passport methods
userSchema.plugin(passportLocalMongoose);
// export modules to be used by the file requiring it
module.exports = mongoose.model("Users",userSchema);
The first entry into the collection occurs as it should but the next ones give
{ [MongoError: E11000 duplicate key error collection: KManV3.users
index: username_1 dup key: { : null }]
name: 'MongoError',
message: 'E11000 duplicate key error collection: KManV3.users index:
username_1 dup key: { : null }',
driver: true,
code: 11000,
index: 0,
errmsg: 'E11000 duplicate key error collection: KManV3.users index:
username_1 dup key: { : null }',
getOperation: [Function],
toJSON: [Function],
toString: [Function]
}
Also, dbname.users.getIndexes() gives:
> db.users.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "KManV3.users"
},
{
"v" : 1,
"key" : {
"password" : 1
},
"name" : "password_1",
"ns" : "KManV3.users",
"background" : true
},
{
"v" : 1,
"unique" : true,
"key" : {
"username" : 1
},
"name" : "username_1",
"ns" : "KManV3.users",
"background" : true
}
]
Apparently every property of schema has been set as unique and I can't add data into collections even if the data is totally different. I'm not sure if it's due to integration of passport.
Looking at the options for passport-local-mongoose:
usernameField: specifies the field name that holds the username. Defaults to 'username'.
usernameUnique : specifies if the username field should be enforced to be unique by a mongodb index or not. Defaults to true.
Which explains why your collection has a unique index on the (non-existent-in-your-schema) username field.
If you don't actually set this field in documents that you add to the database, MongoDB will use null, and once the first document has been inserted, a subsequent document (also with the field value null for username) will throw an E11000 error.
So first, remove the index on username (and also password, I assume you once marked that field as unique in your schema), and set the proper field name for passport-local-mongoose to use:
userSchema.plugin(passportLocalMongoose, { usernameField : 'userName' });
(or email, if you want that field to be used as unique user identifier)
Error reason - The index is not present in your collection, in which you are trying to insert.
Solution - drop that collection and run your program again.

How to take the latest article for each category in mongodb?

I have next article structure:
var articleSchema=new Schema({
id : Number,
title : String,
sefriendly : String,
created : Date,
categories: [
{
id: Number,
name: String,
sefriendly: String,
image: String
}
],
author: {
id: Number,
name: String
}
});
So what I want is to take one latest article sorted by created field for a set of categoryIds. For example I have categories like Cinema, TV, Music, Books, and I want to take latest article for each category. Is it possible to do in one query?
First create index for created date and category ids:
db.article.ensureIndex({"created":-1,"categories.id":1})
then take latest article :
db.article.aggregate( [ {$unwind : "$categories"} { $sort: {"created":-1,"categories.id":1 } }, { $group: { _id: {"categories_id":"$categories.id"}, lastDate: { $last: "$created" } } } ] ,{"allowDiskUse":true})
Maybe there is little syntax error

Array of values

For example I have n doc in MongoDB collection
Films = new Mongo.Collection('films');
Film.insert({name: 'name n', actor: 'John'}); // *n
And I want to show array with only name values
var names = ['name 1', 'name 2',..,'name n'];
Any idea how to do it ?
And guys , ols write in comments correct title value of my question, to help other guys to find it, thx :)
You didn't provided any criteria for grouping name as an array.
You can use following query to get all names:
db.collection.distinct("name")
OR you can use MongoDB's aggregation to get all name by grouping them with some condition, if required. The query will be like following:
db.collection.aggregate({
$group: {
_id: null, //add condition if require
name: {
$push: "$name"
}
}
}, {
$project: {
name: 1,
_id: 0
}
})
If you want only distinct name then replace $push with $addToSet.

Categories

Resources