I am created a mongodb and in the I am filling my client email addresses and there related accounts. But I have found that some values listed as email are not email at all. See the below example.
{
"_id" : ObjectId("591d9cf30ef9acde11d7af6b"),
"email" : "w#Yahoo.com",
"src" : [
{
"acc" : "yahoo",
"name" : "matter"
}
]
}
{
"_id" : ObjectId("591daa540ef9acde11d7af6c"),
"email" : "122",
"src" : [
{
"acc" : "ldd"
}
]
}
I want to check if the key email has the correct value of email or not. If not then I would like to remove the document and make my mongo clean.
How I can achieve that?
Use the remove command using a regex with the $not operator
db.getCollection('somecollection').remove( { email: { $not: /#/ } } )
I'm not 100% sure the regex will work correctly with the # like this. but I would recommend to always test by using find in stead of remove first.
db.getCollection('somecollection').find( { email: { $not: /#/ } } )
Related
I am creating a query to extract description of customers in mongodb. Unfortunately, the description is in HTML Format. Is there a way to replace all HTML tags and make it as " ". Either replace it with " " or remove HTML Tags.
Below is a sample document
{
"_id" : ObjectId("61f72aefdc85500a8baa6bb8")
"CustomerPin" : "22010871",
"CustomerName" : "TestLastName, TestFirstName",
"Age" : 39.0,
"Gender" : "Male",
"Description" : "<p><span>This will be a test description</span><br/></p>",
}
The output should remove "p", "span", and "br". Is there a function in mongodb to remove them all at once without repeating $project
This is the expected output:
{
"_id" : ObjectId("61f72aefdc85500a8baa6bb8")
"CustomerPin" : "22010871",
"CustomerName" : "TestLastName, TestFirstName",
"Age" : 39.0,
"Gender" : "Male",
"Description" : "This will be a test description",
}
Thanks!
One way to do it is by removing all tags by regex in pre hook of save method
Description.replace(/(<([^>]+)>)/gi, "");
See hooks here
If you use Mongo 4.2 then you have to find the exact regex which will extract content from HTML. Below you can find an aggregate pipeline and the regex also.
db.getCollection("name_of_your_collection").aggregate({
$set: {
contentRegex: {
$regexFind: { input: "$Description", regex: /([^<>]+)(?!([^<]+)?>)/gi }
}
}
},
{
$set: {
content: { $ifNull: ["$contentRegex.match", "$Description"] }
}
},
{
$unset: [ "contentRegex" ]
}
)
I'm new to mongo and am trying to do a very simple query in this collection:
{
"_id" : ObjectId("gdrgrdgrdgdr"),
"administrators" : {
"-HGFsfes" : {
"name" : "Jose",
"phone" : NumberLong(124324)
},
"-HGFsfqs" : {
"name" : "Peter",
"phone" : "+43242342"
}
},
"countries" : {
"-dgfgrdg : {
"lang" : "en",
"name" : "Canada"
},
"-grdgrdg" : {
"lang" : "en",
"name" : "USA"
}
}
}
How do I make a query that returns the results of administrators with name like "%Jos%" for example.
What I did until now is this: db.getCollection('coll').find({ "administrators.name": /Jos/});
And variations of this. But every thing I tried returns zero results.
What am I doing wrong?
Thanks in advance!
Your mistake is that administrators is not an array, but an object with fields that are themselves objects with name field. Right query will be
{ "administrators.-HGFsfes.name": /Jos/}
Unfortunatelly this way you're only querying -HGFsfes name field, not other administrator name field.
To achieve what you want, the only thing to do is to replace administrators object by an array, so your document will look like this :
{
"administrators" : [
{
"id" : "-HGFsfes",
"name" : "Jose",
"phone" : 124324
},
{
"id" : "-HGFsfqs",
"name" : "Peter",
"phone" : "+43242342"
}
],
countries : ...
}
This way your query will work.
BUT it will return documents where at least one entry in administrators array has the matching name field. To return only administrator matching element, and not whole document, check this question and my answer for unwind/match/group aggregation pipeline.
You need to use query like this:
db.collection_name.find({})
So if your collection name is coll, then it would be:
db.coll.find({"administrators.-HGFsfes.name": /Jos/});
Look this for like query in mongo.
Also, try with regex pattern like this:
db.coll.find({"administrators..-HGFsfes.name": {"$regex":"Jos", "$options":"i"}}});
It will give you only one result because your data is not an array as below in screenshot:
If you want multiple results, then you need to restructure your data.
Ok, think i've found a better solution for you, with aggregation framework.
Run the following query on your current collection, will return you all administrators with name "LIKE" jos (case insensitive with i option) :
db.test1.aggregate(
[
{
$project: {
administrators:{ $objectToArray: "$administrators"}
}
},
{
$unwind: {
path : "$administrators"
}
},
{
$replaceRoot: {
newRoot:"$administrators"
}
},
{
$match: {
"v.name":/jos/i
}
},
]
);
Output
{
"k" : "-HGFsfes",
"v" : {
"name" : "Jose",
"phone" : NumberLong(124324)
}
}
"k" and "v" are coming from "$objectToArray" operator, you can add a $project stage to rename them (or discard if k value doesn't matter)
Not sure for Robomongo testing but in Studio 3T, formerly Robomongo, you can either copy/paste this query in Intellishell console, or copy/import in aggregation tab, (small icon 'paste from the clipboard').
Hope it helps.
My Document structure is
"MainAccounts" : [
{
"orgs" : "5808ba773fe315441b9e0a9e",
"_id" : ObjectId("5808bc0c3fe315441b9e0b1a"),
"accounts" : [
"5808baf33fe315441b9e0aa7",
"5808baf33fe315441b9e0aa8",
"5808baf33fe315441b9e0aa9",
"5808baf33fe315441b9e0aa1"
]
},
{
"orgs" : "5808ba773fe315441b9e0a9f",
"_id" : ObjectId("5808bc0c3fe315441b9e0b1b"),
"accounts" : [
"5808baf33f35425852s255s7",
"5808baf3sd23s2d3d4w5s2s8",
"5808baf33sd211ds2d2sdsa9",
"5808baf33dssd2d21b9e0aa1"
]
}
],
I want to pull out a particular account say "5808baf33fe315441b9e0aa8" from this, i wrote the query like this.
{ $pull: { "MainAccounts.$.accounts": "5808baf33fe315441b9e0aa8"} }
It gives only error as "The positional operator did not find the match needed from the query. Unexpanded update: MainAccounts.$.accounts"
{ $pull: { "MainAccounts.0.accounts": "5808baf33fe315441b9e0aa8" } }
If i give like this it will remove that value only which gives the expected output.
i need output as
"MainAccounts" : [
{
"orgs" : "5808ba773fe315441b9e0a9e",
"_id" : ObjectId("5808bc0c3fe315441b9e0b1a"),
"accounts" : [
"5808baf33fe315441b9e0aa7",
"5808baf33fe315441b9e0aa9",
"5808baf33fe315441b9e0aa1"
]
},
{
"orgs" : "5808ba773fe315441b9e0a9f",
"_id" : ObjectId("5808bc0c3fe315441b9e0b1b"),
"accounts" : [
"5808baf33f35425852s255s7",
"5808baf3sd23s2d3d4w5s2s8",
"5808baf33sd211ds2d2sdsa9",
"5808baf33dssd2d21b9e0aa1"
]
}
],
here i am not able to delete value from second array i need to give
{ $pull: { "MainAccounts.1.accounts": "5808baf33fe315441b9e0aa8" } }
But i need to loop through, any help is appreciated.
You will get an error:
"Cannot apply $pull to a non-array value"
This should be :
db.collection.update({'MainAccounts.accounts': '5808baf33fe315441b9e0aa8'}, {$pull: {MainAccounts:{ accounts: '5808baf33fe315441b9e0aa8'}}})
Here is a reference to this:
mongodb Cannot apply $pull/$pullAll modifier to non-array, How to remove array element
db.collection.update({someId,{$pull : {"MainAccounts":{"accounts":"5808baf33fe315441b9e0aa8"}}}})
someId could be your _id.
Remember if you have to access the document inside the array you cant access it without . operator only.You have to use the index with it.The other way mongodb can access it is by the use of braces.
This will do what you want:
db.collection.update({'MainAccounts.accounts': '5808baf33fe315441b9e0aa8'}, {$pull: {'MainAccounts.$.accounts': '5808baf33fe315441b9e0aa8'}})
/* 0 */
{
"_id" : ObjectId("55addc2f8dab32aca87ce0bd"),
"partNum" : "part1",
"dest" : "First Part",
"sales" : [
"sale1",
"sale2",
"sale3"
],
"salesData" : {
"sale1" : {
"mcode" : "mc11",
"dtype" : [
"AAA",
"BBB"
]
}
}
}
/* 1 */
{
"_id" : ObjectId("55addc408dab32aca87ce0be"),
"partNum" : "part2",
"dest" : "Second Part",
"sales" : [
"sale1",
"sale2",
"sale3"
],
"salesData" : {
"sale1" : {
"mcode" : "mc22",
"dtype" : [
"AAA",
"BBB"
]
}
}
}
I am not that much efficient in writing mongo script. My requirement is to append one more value to "dtype" array wherever "mcode" is "mc11" in all of the documents inside the collection. Above is the two document output from my collection. I was using the below script to do it and its not working. Can anyone please help me
db.testingRD.find().forEach( function(myDocument)
{
db.testingRD.update({id: myDocument._id}, {$push : {"salesData.sale1.dtype" : "DDD"}});
});
To append one more value to "dtype" array wherever "mcode" is "mc11", use the following update where the query object is the selection criteria for the update and is the same query selector as in the find() method, the update object has the $push modifications to apply and then the options document which is optional. If that is set to true, it updates multiple documents that meet the query criteria:
var query = { "salesData.sale1.mcode": "mc11" },
update = {
"$push": { "salesData.sale1.dtype": "DDD" }
},
options = { "multi": true };
db.testingRD.update(query, update, options);
You had a typing mistake in the script (you forgot an underscore):
db.testingRD.find().forEach( function(myDocument)
{
db.testingRD.update({_id: myDocument._id}, {$push : {"salesData.sale1.dtype" : "DDD"}});
});
I always use a trick when an update seams to not working: I change the update with a printjson + find so that I can see if it is matching anything:
db.testingRD.find().forEach( function(myDocument) { printjson(db.testingRD.find({_id: myDocument._id})) } );
Because of a weird bug in my code, I have a collection with field names which are stricly numbers (ex: 34344,54675,34356).
Now I try to move these fields values to another fields (ex: name,email,etc) but when I run the update command:
db.collection.find({"id_field" : 1996}).forEach(function (elem) {db.collection.update({_id: elem._id},{$set: {name: elem.36536}});});
All I get is an error:
SyntaxError: Unexpected number
How should I handle it? I already tried with elem[36536] instead elem.36536 but without success.
if I got your problem right, this code might help you:
db.collection.find({"id_field" : 1996}).forEach(function (elem)
{
var value = elem['36536'];
db.collection.update({_id: elem._id},{$set: {name: value}});
});
If your document is like this
{
"_id" : 1,
"elem" : {
"123" : "barno",
"456" : "foo#gmail.com"
}
}
you can $rename the key document.
db.d.update({"_id" : 1},{$rename:{'elem.123':'elem.name','elem.456':'elem.email'}})
Result:
{
"_id" : 1,
"elem" : {
"name" : "barno",
"email" : "foo#gmail.com"
}
}