Clean document fromspecial char in mongodb - mongodb

I'm trying to clean all document from a special chars, but something not working as well.
My field descrizione contains some special chars. In this case ^ and -:
^CT 6 STP ANTIPERDITE OLIO MOT BENZ-DIE
db.Collection.find({descrizione: /[$&+,:;=?##|<>.^*()%!-]/g}).forEach(function(doc) {
doc.descrizione = doc.descrizione.replace(/[$&+,:;=?##|<>.^*()%!-]/g,"");
db.Collection.update({ "_id": doc._id },{ "$set": { "descrizione": doc.descrizione } });
});
but something not working as well
This is my document: (Mongo Version 3.4.1)
{
"_id" : ObjectId("60f028bda2255f376aedeb7f"),
"id_am" : "0124525046",
"id_kromeda" : "0124525046",
"descrizione" : "Alternatore",
"prezzo" : "334.60",
"classe" : "200",
"campo_a" : "BOSCH VARI 2",
"campo_b" : "BOSCH VARI 2",
"produttore" : "BOSCH VARI 2",
"prezzo_officine" : "421.60",
"rincaro" : "0%",
"cod_listino" : "027",
"cod_produttore" : "0124525046",
"unita_acquisto" : "1",
"pezzi_unita" : "NR",
"is_enabled" : true,
"cd_type" : "SPARE"
}

You can use Aggregation pipeline with 2 $set stages. In each stage filter out one special character with $replaceAll.
db.collection.update({},
[
{
$set: {
descrizione: {
$replaceAll: {
input: "$descrizione",
find: "^",
replacement: ""
}
}
}
},
{
$set: {
descrizione: {
$replaceAll: {
input: "$descrizione",
find: "-",
replacement: ""
}
}
}
}
],
{
multi: true
})
Working example

Related

Query to update showing 0 records updated mongo

Am using below query in db.getcolletion
db.getCollection('publickdata').find({"mediatorProf" : "ctvdl Without audieo",
"ProfileName":"p2_max_dls",ProfileDetails:
{ $elemMatch: { Name: "psMaxdetail", Value: "Mozilla 13" } }})
I need to update Value: Mozilla 13 to Value: Mozilla 12
Am using below query:
db.collection.update( // or updateMany directly, removing the flag for 'multi'
{"elemMatch.Value":"Mozilla 13"},
{$set:{"elemMatch.$[].Value":"Mozilla 12"}}, // notice the empty brackets after '$' opearor
false,
true
)
output showing: Updated 0 records provide suggestions.
document is:
/* 1 */
{
"_id" : ObjectId("5e31a24faa0f99e"),
"lastUpdateDate" : ISODate("2020-02-29T16:18:39.664Z"),
"mediatorProf" : "ctvdl Without audieo",
"ProfileName" : "p2_max_dls",
"ProfileDetails" : [
{
"Name" : "psMaxdetail",
"Value" : "Mozilla 13"
},
{
"Name" : "iptvSupported",
"Value" : "N"
}
]
}
Use $[identifier] along with arrayFilters.
db.publickdata.updateMany(
{
"mediatorProf": "ctvdl Without audieo",
"ProfileName": "p2_max_dls"
},
{
$set:{
"ProfileDetails.$[elem].Value": "Mozilla 12"
},
$unset:{
"ProfileDetails.$[elem].AttributeValue": 1
}
},
{
multi: true,
arrayFilters: [{"elem.Name": "psMaxdetail", "elem.Value": "Mozilla 13"}]
}
);

Using MongoDB $set to update multiple subdocuments

I have such Article-documents:
{
"_id" : "rNiwdR8tFwbTdr2oX",
"createdAt" : ISODate("2018-08-25T12:23:25.797Z"),
"title" : "Happy",
"lines" : [
{
"id" : "5efa6ad451048a0a1807916c",
"text" : "Test 1",
"align" : "left",
"indent" : 0
},
{
"id" : "ae644f39553d46f85c6e1be9",
"text" : "Test 2"
},
{
"id" : "829f874878dfd0b47e9441c2",
"text" : "Test 3"
},
{
"id" : "d0a46ef175351ae1dec70b9a",
"text" : "Test 4"
},
{
"id" : "9bbc8c8d01bc7029220bed3f",
"text" : "Test 5"
},
{
"id" : "6b5c02996a830f807e4d8e35",
"text" : "Test 6",
"indent" : 0
}
]
}
I need to update some Lines.
For example I have array with ids of the line which must be updated.
let lineIds = [
"5efa6ad451048a0a1807916c",
"829f874878dfd0b47e9441c2",
"6b5c02996a830f807e4d8e35"
];
So I try to update attributes "attr" for the "lines" and I do following:
'articles.updateLines': function (articleId, lineIds, attr, value) {
return Articles.update({
'_id': articleId,
'lines.id': { $in: lineIds }
},
{
$set: {
['lines.$.' + attr]: value
}
},
{ multi: true }
);
}
The problem is that just the first line (with id="5efa6ad451048a0a1807916c") is updated.
Any ideas? Thanks! :)
You can use $[]. This will works only MongoDB version 3.6 and above.
Refer link :
https://docs.mongodb.com/manual/reference/operator/update/positional-all/
You can also see this stackoverflow question reference:
How to add new key value or change the key's value inside a nested array in MongoDB?
You can convert below query in your function
db.col.update(
{ '_id':"rNiwdR8tFwbTdr2oX", },
{ $set: { "lines.$[elem].text" : "hello" } },
{ arrayFilters: [ { "elem.id": { $in: lineIds } } ],
multi: true
})
'lines.id': { $in: lineIds }
This won't work, because lines is an array.
What I understand from your question, you can prepare a new array with proper processing and replace the lines array with the new one. Here is an idea how to do this:
'articles.updateLines': function (articleId, lineIds, attr, value) {
let lines = Articles.findOne(articleId).lines;
// prepare a new array with right elements
let newArray = [];
for(let i=0; i<lines.length; i++){
if(lineIds.includes(lines[i].id)){
newArray.push(value)
}
else newArray.push(lines[i])
}
return Articles.update({
'_id': articleId,
},
{
$set: {
lines: newArray
}
}
);
}

How to update a mongodb object using multiple selection criteria

My schema structure looks something like this:
{
"__v":0,
"_id":ObjectId("5708423e897db8255aaaa9dd"),
"podId":169400000005,
"env":[
{
"type":"1",
"id":3852000000035,
"_id":ObjectId("5708423e897db8255aaaa9de")
},
{
"type":"2",
"id":3852000000040,
"_id":ObjectId("5708423e897db8255aaaa9df")
}
],
"name":"Test Build",
"parameters":[
{
"name":"sound.left",
"type":"1",
"paramName":"Left Sound Control",
"paramType":"booleanParameter",
"testValue":null,
"liveValue":null,
"_id":ObjectId("5708423f897db8255aaaaa0d")
},
{
"name":"sound.right",
"type":"1",
"paramName":"Right Sound Control",
"paramType":"booleanParameter",
"testValue":null,
"liveValue":null,
"_id":ObjectId("5708423f897db8255aaaaa0d")
},
...
]
}
I have 3 known variables: podId for podId, codeName for parameters.name, envType for parameters.type. Using them I want to update the object using podId, codeName, and envType, with a new variable paramValue that will contain the testValue value.
What I've tried
db.pods.update({
podId: podId,
parameters: {
$elemMatch: {
name: codeName,
type: envType
}
}
}, {
$set: {
'parameters.$.testValue': paramValue
}
});
I'm trying to update the testValue where podId == podId, parameters.name == codeName, and parameters.type == envType, but the above did not update anything.
I also tried
db.pods.update({
podId: podId,
parameters: {
name: codeName,
type: envType
}
}, {
$push: {
parameters: {
testValue: paramValue
}
}
},
function(err) {
if(err) throw err;
});
basically taking what worked to build the object when I only had to compare the podId, and adding the extra criteria; it didn't work this time.
edit: fixed schema type Number to String
Let these are variables that you have in mongo shell:
> var podId = 169400000005
> var codeName = "sound.right"
> var envType = "1"
> var paramValue = "updatedParamValue"
This query you can try:
db.test.update({"podId":podId, "parameters.name" : codeName, "parameters.type" : envType}, {$set : {"parameters.0.testValue" : paramValue,"parameters.1.testValue" : paramValue}})
Depending upon which testValue you want to update, you can pass index to that.
Update
Following result i get after the update query:
db.test.find().pretty()
{
"_id" : ObjectId("570c850ab9477f18ac5297f9"),
"__v" : 0,
"podId" : 169400000005,
"env" : [
{
"type" : "1",
"id" : 3852000000035,
"_id" : ObjectId("5708423e897db8255aaaa9de")
},
{
"type" : "2",
"id" : 3852000000040,
"_id" : ObjectId("5708423e897db8255aaaa9df")
}
],
"name" : "Test Build",
"parameters" : [
{
"name" : "sound.left",
"type" : "1",
"paramName" : "Left Sound Control",
"paramType" : "booleanParameter",
"testValue" : "updatedParamValue",
"liveValue" : null,
"_id" : ObjectId("5708423f897db8255aaaaa0d")
},
{
"name" : "sound.right",
"type" : "1",
"paramName" : "Right Sound Control",
"paramType" : "booleanParameter",
"testValue" : "updatedParamValue",
"liveValue" : null,
"_id" : ObjectId("5708423f897db8255aaaaa0d")
}
]
}
Thanks.

Project with Match in aggregate not working after use substr in mongodb

I have face one use with mongodb.
below is my sample record.
{
"_id" : ObjectId("56fa21da0be9b4e3328b4567"),
"us_u_id" : "1459169911J4gPxpYQ7A",
"us_dealer_u_id" : "1459169911J4gPxpYQ7A",
"us_corporate_dealer_u_id" : "1459169173rgSdxVeMLa",
"us_oem_u_id" : "1459169848CK5yOpXito",
"us_part_number" : "E200026",
"us_sup_part_number" : "",
"us_alter_part_number" : "",
"us_qty" : 0,
"us_sale_qty" : 2,
"us_date" : "20160326",
"us_source_name" : "BOMAG",
"us_source_address" : "",
"us_source_city" : "",
"us_source_state" : "",
"us_zip_code" : "",
"us_alternet_source_code" : "",
"updated_at" : ISODate("2016-03-29T06:34:02.728Z"),
"created_at" : ISODate("2016-03-29T06:34:02.728Z")
}
I have try to get all recored having unique date
So, I have made below query using aggregate
.aggregate(
[
{
"$match":{
"yearSubstring":"2016",
"monthSubstring":"03",
"us_dealer_u_id":"1459169911J4gPxpYQ7A"
}
},
{
"$project":
{
"yearSubstring":{"$substr":["$us_date",0,4]},
"monthSubstring":{"$substr":["$us_date",4,2]},
"daySubstring":{"$substr":["$us_date",6,2]}
}
},
{
"$group":
{
"_id":{"monthSubstring":"$monthSubstring",
"yearSubstring":"$yearSubstring",
"daySubstring":"$daySubstring"
},
"daySubstring":{"$last":"$daySubstring"}
}
},
{"$sort":{"us_date":1}}
]
)
I have try both way to pass year and month (as string and as int)
but I have get blank result.
if I'm remove month and year from condition then record came.
mostly I have try all the diff. diff. solution but result is same.
Thank in advance.
You have written incorrect query.
You don't have yearSubstring and monthSubstring fields on this stage.
{
"$match":{
"yearSubstring":"2016",
"monthSubstring":"03",
"us_dealer_u_id":"1459169911J4gPxpYQ7A"
}
},
You should write as following:
.aggregate(
[
{
"$match":{
"us_dealer_u_id":"1459169911J4gPxpYQ7A"
}
},
{
"$project":
{
"yearSubstring":{"$substr":["$us_date",0,4]},
"monthSubstring":{"$substr":["$us_date",4,2]},
"daySubstring":{"$substr":["$us_date",6,2]}
}
},
{
"$match":{
"yearSubstring":"2016",
"monthSubstring":"03"
}
},
{
"$group":
{
"_id":{"monthSubstring":"$monthSubstring",
"yearSubstring":"$yearSubstring",
"daySubstring":"$daySubstring"
},
"daySubstring":{"$last":"$daySubstring"}
}
},
{"$sort":{"us_date":1}}
]
)
If you want to get other fields, you should include them into projection stage.

Case Insensitive search with $in

How to search a column in a collection in mongodb with $in which includes an array of elements for search and also caseInsensitive matching of those elements in the column ?
Use $in with the match being case insensitive:
Data example:
{
name : "...Event A",
fieldX : "aAa"
},
{
name : "...Event B",
fieldX : "Bab"
},
{
name : "...Event C",
fieldX : "ccC"
},
{
name : "...Event D",
fieldX : "dDd"
}
And we want documents were "fieldX" is contained in any value of the array (optValues):
var optValues = ['aaa', 'bbb', 'ccc', 'ddd'];
var optRegexp = [];
optValues.forEach(function(opt){
optRegexp.push( new RegExp(opt, "i") );
});
db.collection.find( { fieldX: { $in: optRegexp } } );
This works for $all either.
I hope this helps!
p.s.: This was my solution to search by tags in a web application.
You can use $elemMatch with regular expressions search, e.g. let's search for "blue" color in the following collection:
db.items.save({
name : 'a toy',
colors : ['red', 'BLUE']
})
> ok
db.items.find({
'colors': {
$elemMatch: {
$regex: 'blue',
$options: 'i'
}
}
})
>[
{
"name": "someitem",
"_id": { "$oid": "4fbb7809cc93742e0d073aef"},
"colors": ["red", "BLUE"]
}
]
This works for me perfectly.
From code we can create custom query like this:
{
"first_name":{
"$in":[
{"$regex":"^serina$","$options":"i"},
{"$regex":"^andreW$","$options":"i"}
]
}
}
This will transform to following in mongo after query:
db.mycollection.find({"first_name":{"$in":[/^serina$/i, /^andreW$/i]}})
Same for "$nin".
This is pretty simple
const sampleData = [
RegExp("^" + 'girl' + "$", 'i'),
RegExp("^" + 'boy' + "$", 'i')
];
const filerObj = { gender : {$in : sampleData}};
The way to do it in Java is:
List<String> nameList = Arrays.asList(name.split(PATTERN));
List<Pattern> regexList = new ArrayList<>();
for(String name: nameList) {
regexList.add(Pattern.compile(name , Pattern.CASE_INSENSITIVE));
}
criteria.where("Reference_Path").in(regexList);
Here is my case insensitive search (query) with multiple condition (regex) from data of array, I've used $in but it doesn't support case insensitive search.
Example Data
{
name : "...Event A",
tags : ["tag1", "tag2", "tag3", "tag4]
},
{
name : "...Event B",
tags : ["tag3", "tag2"]
},
{
name : "...Event C",
tags : ["tag1", "tag4"]
},
{
name : "...Event D",
tags : ["tag2", "tag4"]
}
My query
db.event.find(
{ $or: //use $and or $or depends on your needs
[
{ tags : {
$elemMatch : { $regex : '^tag1$', $options : 'i' }
}
},
{ tags : {
$elemMatch : { $regex : '^tag3$', $options : 'i' }
}
}
]
})