I need to remove the domain name from the URL in the JSON array stored in Mongo DB using Mongoose.
JSON Array format in DB
{
"_id": {
"$oid": "602a482223df2a16e26f51bc"
},
"message": "Test Again",
"pollType": {
"$numberInt": "1"
},
"type": "TEST",
"optionList": [
{
"name": "name",
"original": "https://name/test/pictures/1613383695668-71393-0d1f829222f945dc",
"thumbnail": "https://name/test/pictures/1613383695668-71393-0d1f829222f945dc",
"vote": {
"$numberInt": "1"
},
"_id": {
"$oid": "602a482223df2a16e26f51b9"
},
"participateUser": [
{
"$oid": "5c9baa00bcafa608891b0b44"
}
],
"latestParticipate": [
{
"$oid": "5c9baa00bcafa608891b0b44"
}
]
},
{
"name": null,
"original": "https://name/test/pictures/1613383695672-71393-e92a34eaf6b48b19",
"thumbnail": "https://name/test/pictures/1613383695672-71393-e92a34eaf6b48b19",
"vote": {
"$numberInt": "0"
},
"_id": {
"$oid": "602a482223df2a16e26f51ba"
},
"participateUser": [
]
},
{
"name": null,
"original": "https://name/test/pictures/1613383695630-71393-3387191491ba279c",
"thumbnail": "https://name/test/pictures/1613383695630-71393-3387191491ba279c",
"vote": {
"$numberInt": "0"
},
"_id": {
"$oid": "602a482223df2a16e26f51bb"
},
"participateUser": [
]
}
],
"pollId": {
"$oid": "602a482223df2a16e26f51b8"
},
"createdAt": {
"$date": {
"$numberLong": "1613383714396"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1613383714396"
}
},
"totalVoteCount": {
"$numberInt": "1"
},
"participateUser": [
{
"$oid": "5c9baa00bcafa608891b0b44"
}
]
}
I am using below code to replace a string
return new Promise(async (resolve, reject) => {
console.log("Iam called")
MongoClient.connect('mongoDBconfig', function (err, client) {
if (err) throw err;
var collection = "test"
var db = client.db('testDB');
db.collection(collection).updateMany({
"optionList.thumbnail": { $regex: /name/ },
}, {
"$set": {
"optionList.$.thumbnail": {
$replaceOne: { input: "optionList.$.thumbnail", find: "https://name/test", replacement: "" },
}
}
}
}, function (error, success) {
if (success) {
resolve(success)
}
else {
reject(error)
}
})
})
})
but when I call this function I getting below error
DB Error : Duplicate Entry : dollar ($) prefixed field '$replaceOne' in 'optionList.0.original.$replaceOne' is not valid for storage.
The $replaceOne is a aggregation operator starting from MongoDB v4.4, you can use update with aggregation pipeline starting from MongoDB v4.2
$map to iterate loop of optionList array
$replaceOne to replace string
$mergeObjects to merge current object with updated original field
let originalName = "https://name/test";
db.collection(collection).updateMany(
{ "optionList.original": { $regex: originalName } },
[{
$set: {
optionList: {
$map: {
input: "$optionList",
in: {
$mergeObjects: [
"$$this",
{
thumbnail: {
$replaceOne: {
input: "$$this.thumbnail",
find: originalName,
replacement: ""
}
}
}
]
}
}
}
}
}],
function (error, success) {
if (success) { resolve(success) }
else { reject(error) }
}
)
Playground
Related
Hi i am new in mongoose and mongodb. I want to remove specific object from the Array in my document and return the updated document. I have tried a lot but it always return null. Here is my document structure.
{
"role": "Student",
"skills": [
"html",
"css",
"js"
],
"_id": "5ef583198e9b23cc8c606c10",
"user": "5ee5c9ef26333935647e54bc",
"__v": 24,
"status": "Intern",
"education": [],
"internships": [
{
"current": false,
"_id": "5ef894d48f601512340f25b5",
"title": "Web",
"company": "asdfadfd",
"from": "2010-02-04T00:00:00.000Z"
},
{
"current": false,
"_id": "5ef894f31dc9413bf89c44d8",
"title": "Django",
"company": "example",
"from": "2010-02-04T00:00:00.000Z"
}
]
}
And here is my updating function
exports.deleteStudentInternship = async (req, res, next) => {
const deleteInternship = await Student.findOneAndUpdate(
{ $and: [{ user: req.user.id }, { 'internships': { $elemMatch: { _id: req.params.intern_id } } }] },
{ '$pull': { 'internships': { _id: req.params.intern_id } } },
{
new: true,
useFindAndModify: false,
},
function (error) {
if (error) return validationError(404, { internship: 'Internship id not exist' }, next)
}
);
if (!deleteInternship) {
return validationError(404, { internship: 'Internship id not exist' }, next)
}
res.status(200).json(deleteInternship);
}
Please change the pull part I mean
{ '$pull': { 'internships': { _id: req.params.intern_id } } }
to this and try:
{ '$pull': { 'internships': req.params.intern_id } }
I have this scheme
{
"_id": {
"$oid": "5e187b1791c51b4b105fcff0"
},
"username": "test",
"email": "test#test.com",
"role": "admin",
"userScoreFantasy": {
"tournaments": [
{
"tournament_id": {
"$oid": "5e1892fb480f344830a3f160"
},
"predictions": [],
"score": null
},
{
"tournament_id": {
"$oid": "5e189f5f8d88292754e10b37"
},
"predictions": [],
"score": null
}
],
"totalScore": null
},
}
I want to do this :
Find user with a predefined user id
Pass all userScoreFantasy.tournaments array to find a specific tournament id
Push into the found tournament predictions array an object like this one :
{
score,
"match_id": foundMatch._id
}
So the tournaments array will become :
[
{
"tournament_id": {
"$oid": "5e1892fb480f344830a3f160"
},
"predictions": [
"score" : 200,
"match_id": "5e1892fb480f34faw21410"
],
"score": null
},
]
I tried to do this :
Users.update({
"_id": prediction.user_id,
"userScoreFantasy.tournaments": {
"$elemMatch": {
"tournament_id": foundMatch.tournament_id
}
}
}, {
"$push": {
"userScoreFantasy.tournaments.$.predictions": {
score,
"match_id": foundMatch._id
}
}
})
But the array is not updating.
EDIT :
Working call :
Users.updateOne({
"_id": ObjectID(prediction.user_id),
}, {
$addToSet: {
"userScoreFantasy.tournaments.$[element].predictions": {
score,
"match_id": foundMatch._id
}
}
}, {
arrayFilters: [{
"element.tournament_id": ObjectID(foundMatch.tournament_id)
}]
}
)
You should use the position indentifier to update your arrays, like so:
Users.updateOne(
{
"_id": prediction.user_id,
},
{
$addToSet: {
"userScoreFantasy.tournaments.$[element].predictions": {
score,
"match_id": foundMatch._id
}
}
},
{arrayFilters: [{"element.tournament_id": foundMatch.tournament_id}]}
);
I'm trying to delete a subdocuments in array with Mongoose.
My datas :
{
"_id": {
"$oid": "5d88dfe45feb4c06a5cfb762"
},
"spaces": [{
"_id": {
"$oid": "5d88dfe45feb4c06a5cfb76f"
},
"name": "Building 2",
"subSpace": [{
"_id": {
"$oid": "5d88dfe45feb4c06a5cfb771"
},
"name": "Basement"
}, {
"_id": {
"$oid": "5d88dfe45feb4c06a5cfb770"
},
"name": "Floors"
}]
}, {
"_id": {
"$oid": "5d88dfe45feb4c06a5cfb76c"
},
"name": "Building 4",
"subSpace": [{
"_id": {
"$oid": "5d88dfe45feb4c06a5cfb76e"
},
"name": "Basement"
}, {
"_id": {
"$oid": "5d88dfe45feb4c06a5cfb76d"
},
"name": "Floors"
}]
}]
}
For this example, we want to delete the subSpace Floors in Building 2 with this _id : 5d88dfe45feb4c06a5cfb771
My code (in the model) :
exports.removeSubSpaceById = (subSpaceId) => {
Residence.findOneAndUpdate( { "spaces.subSpace._id": '5d88dfe45feb4c06a5cfb771' },
{ $pull:
{ spaces:
{ subSpace:
{ _id: '5d88dfe45feb4c06a5cfb771' }}}}, function(err, result) {
console.log(result);
})
};
Output : console.log : my entire document
But the subSpace/Basement (5d88dfe45feb4c06a5cfb771) is still in my document.
Thanks for your help.
Use positional operator for nested array operations. MongoDb Docs
exports.removeSubSpaceById = (subSpaceId) => {
Residence.findOneAndUpdate({ "spaces._id": '5d88dfe45feb4c06a5cfb76f' },
{
$pull:
{
"spaces.$.subSpace": { _id: "5d88dfe45feb4c06a5cfb771" }
}
}, function (err, result) {
console.log(result);
})
}
I have collection trusted contacts. I need to filter the document by the user. When I use method findOne I have a result, but when I use $match I got an empty array. I don't know why $match doesn't work for me.
Collection trusted contacts:
{
"_id": {
"$oid": "5d76008e4b98e63e58cb34cc"
},
"date": {
"$date": "2019-09-09T07:32:20.174Z"
},
"approvedTrustedContacts": [
{
"_id": {
"$oid": "5d764e411b7476462cf6b540"
},
"user": {
"$oid": "5c5ecaf6134fc342d4b1a9d5"
}
},
{
"_id": {
"$oid": "5d7750af52352918f802c474"
},
"user": {
"$oid": "5c64968cae53a8202c963223"
}
}
],
"pendingApprovalContacts": [],
"waitingForApprovalContacts": [],
"user": {
"$oid": "5d76008e4b98e63e58cb34cb"
}
},
{
"_id": {
"$oid": "5d7605f5e7179a084efa385b"
},
"date": {
"$date": "2019-09-09T07:32:20.174Z"
},
"approvedTrustedContacts": [
{
"_id": {
"$oid": "5d764e411b7476462cf6b541"
},
"user": {
"$oid": "5d76008e4b98e63e58cb34cb"
}
}
],
"pendingApprovalContacts": [],
"waitingForApprovalContacts": [],
"user": {
"$oid": "5c5ecaf6134fc342d4b1a9d5"
}
}
when I use method findOne
const user = await TrustedContacts.findOne({ user: "5d76008e4b98e63e58cb34cb" })
I have result
but when I use $match I got empty array
result1 = await TrustedContacts.aggregate([
{ $match: { user: "5d76008e4b98e63e58cb34cb" } },
]);
It Works,
const ObjectId = require('mongodb').ObjectId;
result1 = await TrustedContacts.aggregate([
{ $match: { user: ObjectId("5d76008e4b98e63e58cb34cb") } },
]);
I'm getting started with ElasticSearch and I'm getting into troubles (I'm not understanding as It has to be) how to search.
First, I have this two documents:
{
"took": 133
"timed_out": false
"_shards": {
"total": 5
"successful": 5
"failed": 0
}
"hits": {
"total": 2
"max_score": 1
"hits": [2]
0: {
"_index": "app"
"_type": "player"
"_id": "AVcLCOgAi_gt2Fih02MK"
"_score": 1
"_source": {
"nickName": "sarasa"
"birthDate": "1994-11-05T13:15:30.000Z"
"state": "sarasa"
"adminState": "sarasa"
"id": ""
"account": {
"type": "yojuego"
"id": "asasdfa"
"password": "asd fasd"
}
}
}
1: {
"_index": "app"
"_type": "player"
"_id": "AVcQ7JNVi_gt2Fih02MN"
"_score": 1
"_source": {
"nickName": "facundo"
"birthDate": "1994-11-05T13:15:30.000Z"
"state": "verdura"
"adminState": "sudo"
"id": ""
"account": {
"type": "yojuego"
"id": "facundo#facundo"
"password": "pepe"
}
}
}
}
}
}
I want to get where account.id = "facundo#facundo" and account.type = "yojuego".
I'm doing this:
client.search({
index: 'app',
type: 'player',
query: {
bool: {
must: [
{ term: { "account.id": 'facundo#facundo' } },
{ term: { "account.type": 'yojuego' } }
],
}
}
}, (error, response, status) => {
if (error) {
res.json(400, err);
}
else {
res.json(200, response.hits.hits);
}
});
This search is retrieving all documents I have into the index.
Any help?
Thanks!
PD: Here is how I created index and mapping:
client.indices.create({ index: 'yojuego' }, (err, resp, respcode) => {
if (!err) {
client.indices.putMapping({
index: 'app',
type: "player",
body: {
properties: {
nickName: { type: "string" },
birthDate: { type: "string" },
state: { type: "string" },
adminState: { type: "string" },
account: {
type: "nested",
properties: {
id: { type: "string" },
type: { type: "string" },
password: { type: "string" }
}
}
}
}
}, (err, resp, respcode) => {
res.json(200, resp);
});
}
});
make sure that account is a nested field and then apply this query,
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "account",
"query": {
"bool": {
"must": [
{
"match": {
"account.id": "facundo#facundo"
}
},
{
"match": {
"account.type": "yojuego"
}
}
]
}
}
}
}
]
}
}
}