Check if a value exists in array using aggregation - mongodb

I'm using mongoDB version 3.2. and i want to check if a string is exist in an array of string, i want to use the regex so if just a part of the given string is exist in a string in the array, that record should be returned.
here's an example of a record:
{
name: "initiative 1",
portfolioItems: ["Non clinical", "ITS portfolio", "Lean"]
}
the following query does not work:
db.collection.aggregate([
{
$match:
{ 'portfolioItems' : { $in: [/term/] } }
}
])
is there anyway to achieve that ?

Try this one.
db.collection.aggregate([
{
$match:
{"portfolioItems":{'$regex':"^it", '$options': 'i'}}
}
])
The symbol ^ used to start from the first of string. If u don't need it. You can remove it.
Your query become
{
$match:
{"portfolioItems":{'$regex':"^"+term, '$options': 'i'}}
}

You have to match the pattern in each element of array.
Try this :
{ 'portfolioItems' : { $regex: [/term/] } }

Related

mongoose search text in nested object

there is a nested mongodb document that looks like the image below. I want to do a search in the body field in this document, but I could not succeed. how can i do this search. thanks in advance
I tried to search like this. Is my path correct?
const result = await this.campaignModel.find({
"sequencesPageData": {
"$elemMatch": {
"mailSteps": {
"$elemMatch": {
"mailTemplate": x
}
}
}
}
});
I did a search like this but got no results.
const result = await this.campaignModel.find({
"sequencesPageData": {
"$elemMatch": {
"mailSteps": {
"$elemMatch": {
"mailTemplate": x
}
}
}
}
});
For object fields, simply access them using dot notation. For array fields, use $elemMatch to perform the match.
db.collection.find({
"sequencesPageData.mailSteps": {
"$elemMatch": {
"mailTemplate": {
"$elemMatch": {
"subject": "asdf"
}
}
}
}
})
Mongo Playground
If you are only testing a single field in the array, there is no need to use $elemMatch, you can use dot notation:
db.collection.find({ "sequencesPageData.mailSteps.mailTemplate.body": "x" })
$elemMatch is useful to ensure that 2 or more tests are satisfied by the same array element, but since this example uses only 1 test, it works without.

How To FindOne Doccument in Array of Object MongoDb?

I Have document like this.
{
accountId: "182092109",
documents:[{
idDocuments:"0000",
filePath :"/data/photo/1.png",
status:"EXIST"
},
{
idDocuments:"0001",
filePath :"/data/photo/2.png",
status:"EXIST"
}]
}
but i need document to be like
{
idDocuments:"0001",
filePath :"/data/photo/2.png",
status:"EXIST"
}]
}
is it possible ? or is this have alternative to findOne document in mongo into like that ?
Thank's in Advance
As far as I understand you want to find a specific document in an array of objects.
You can use the $elemMatch operation within a find() method. To return only matching results.
You can try something like this:
db.collection.find({
arrayOfObjects: {
$elemMatch: { // Finding only the ones that match
idDocuments:"0001",
filePath :"/data/photo/2.png",
status:"EXIST"
}
}
})
If your $elemMatch returns more than 1 result, you can limit the find() method using the $limit operator.
db.collection.find({
arrayOfObjects: {
$elemMatch: { // Finding only the ones that match
idDocuments:"0001",
filePath :"/data/photo/2.png",
status:"EXIST"
}
}
}, {
arrayOfObjects: {
$limit: 1 // Limiting results
}
})
Most of the information can be found in MongoDB Manual.
Or you can read more here.

mongodb query: nested elemMatch

Currently, that's my current document:
{
_id: 'd283015f-91e9-4404-9202-093c28d6a931',
referencedGeneralPractitioner: [
{
resourceType: 'practitioner',
cachedIdentifier: [
{
system: { value: 'urn:oid:1.3.6.1.4.1.19126.3' },
value: { value: '14277399B' }
}
]
}
]
}
Here, there's two nested objects arrays: referencedGeneralPractitioner[{cachedIdentifier[{}]}].
Currently, I'm getting results using this query:
{
"referencedGeneralPractitioner":{
"$elemMatch":{
"cachedIdentifier.value.value":"14277399B",
"cachedIdentifier.system.value":"urn:oid:1.3.6.1.4.1.19126.3"
}
}
}
It's getting my desired document, but I don't quite figure out if above query is which I'm really looking for.
I mean, I'm only applying $elemMatch on referencedGeneralPractitioner field array.
Is it really enought?
Should I add a nested $elemMatch on cachedIdentifier?
Any ideas?
It looks like you need to query it like this:
db.collection.find({
"referencedGeneralPractitioner.cachedIdentifier": {
"$elemMatch": {
"value.value": "14277399B",
"system.value": "urn:oid:1.3.6.1.4.1.19126.3"
}
}
})
playground
This is in case you need to find the full document having $and of both values in same element in any of the elements in the nested array , if you need to extract specific element you will need to $filter
if you need to search also based on element in the 1st array level then you need to modify as follow:
{
"referencedGeneralPractitioner": {
"$elemMatch": {
resourceType: 'practitioner',
"cachedIdentifier": {
"$elemMatch": {
"value.value": 1,
"system.value":2
}
}
}
}
}
This will give you all full documents where at same time there is resouceType:"practitioner" and { value.value:3 and system.value: 2 }
Also is important to stress that this will not gona work correctly!:
{
"referencedGeneralPractitioner":{
"$elemMatch":{
"cachedIdentifier.value.value":"14277399B",
"cachedIdentifier.system.value":"urn:oid:1.3.6.1.4.1.19126.3"
}
}
}
Since it will match false positives based on any single value in the nested elements like:
wrong playground

Deleting array from collection

I am facing an issue in deleting an array from db.
I want to delete the [2] array with its id as condition.
I have tried many things, but none give results as expected.
db.users.update({ '_id': ObjectId("53689fa45bac9757f81fbb77")},{ '$pull' : { 'injury._id': ObjectId("5379974ac76d005c2d00005c") } })
Use the $pull operator to remove the element you do not want:
db.collection.update(
{ "injury._id": ObjectId("53760d9820b6ee683000005c") },
{
"$pull": {
"injury": { "_id": ObjectId("53760d9820b6ee683000005c") }
}
}
)
Forgive me if the actual _id values do not match as you posted a screenshot.
I guess, something like this should work
.update(..., { $pull: { injury: {_id: YOUR_ID } } })
The format of $pull is
$pull: { arrayName: { array item query } }
You can use unset() if you're using PHP

MongoDB update. Trying to set one field from a property of another

What I'm trying to do is pretty straightforward, but I can't find out how to give one field the value of another.
I simply want to update one field with the character count of another.
db.collection.update({$exists:true},{$set : {field1 : field2.length}})
I've tried giving it dot notation
db.collection.update({$exits:true},{$set : {field1: "this.field2.length"}})
As well as using javascript syntax
db.collection.update({$exits:true},
{$set : {field1: {$where : "this.field2.length"}})
But just copied the string and got a "notOkforstorage" respectively. Any help?
Update:
I only get the "notOkforStorage" when I query by ID:
db.collection.update({_id:ObjectID("38289842bbb")},
{$set : {field1: {$where :"this.field2.length"}}})
Try the following code:
db.collection.find(your_querry).forEach(function(doc) {
doc.field1 = doc.field2.length;
db.collection.save(doc);
});
You can use your_querry to select only part of the original collection do perform an update. If you want to process an entire collection, use your_querry = {}.
If you want all operations to be atomic, use update instead of save:
db.collection.find( your_querry, { field2: 1 } ).forEach(function(doc) {
db.collection.update({ _id: doc._id },{ $set: { field1: doc.field2.length } } );
});
Starting Mongo 4.2, db.collection.update() can accept an aggregation pipeline, finally allowing the update/creation of a field based on another field:
// { "_id" : ObjectId("5e84c..."), "field1" : 12, "field2" : "world" }
db.collection.update(
{ "_id" : ObjectId("5e84c...") },
[{ $set: { field1: { $strLenCP: "$field2" } } }]
)
// { "_id" : ObjectId("5e84c..."), "field1" : 5, "field2" : "world" }
The first part {} is the match query, filtering which documents to update.
The second part [{ $set: { field1: { $strLenCP: "$field2" } } }] is the update aggregation pipeline (note the squared brackets signifying the use of an aggregation pipeline). $set is a new aggregation operator and an alias for $addFields. Any aggregation operator can be used within the $set stage; in our case $strLenCP which provides the length of field2.
As far I know the easiest way is the read and write aproach:
//At first, get/prepare your new value:
var d= db.yourColl.fetchOne({....});
d.field1== d.field2.length;
// then update with your new value
db.yourColl.save(d);
Your are using exists in the wrong way.
Syntax: { field: { $exists: <boolean> } }
You use of $where is also incorrect
Use the $where operator to pass either a string containing a JavaScript expression or a full JavaScript function to the query system
db.myCollection.find( { $where: "this.credits == this.debits" } );
db.myCollection.find( { $where: "obj.credits == obj.debits" } );
db.myCollection.find( { $where: function() { return (this.credits == this.debits) } } );
db.myCollection.find( { $where: function() { return obj.credits == obj.debits; } } );
I think you should use Map-Reduce for what you are trying to do.