How To FindOne Doccument in Array of Object MongoDb? - 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.

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.

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

Most efficient way to put fields of an embedded document in its parent for an entire MongoDB collection?

I am looking for the most efficient way to modify all the documents of a collection from this structure:
{
[...]
myValues:
{
a: "any",
b: "content",
c: "can be found here"
}
[...]
}
so it becomes this:
{
[...]
a: "any",
b: "content",
c: "can be found here"
[...]
}
Basically, I want everything under the field myValues to be put in its parent document for all the documents of a collection.
I have been looking for a way to do this in a single query using dbCollection.updateMany(), put it does not seem possible to do such thing, unless the content of myValues is the same for all documents. But in my case the content of myValues changes from one document to the other. For example, I tried:
db.getCollection('myCollection').updateMany({ myValues: { $exists: true } }, { $set: '$myValues' });
thinking it would perhaps resolve the myValues object and use that object to set it in the document. But it returns an error saying it's illegal to assign a string to the $set field.
So what would be the most efficient approach for what I am trying to do? Is there a way to update all the documents of the collection as I need in a single command?
Or do I need to iterate on each document of the collection, and update them one by one?
For now, I iterate on all documents with the following code:
var documents = await myCollection.find({ myValues: { $exists: true } });
for (var document = await documents.next(); document != null; document = await documents.next())
{
await myCollection.updateOne({ _id: document._id }, { $set: document.myValues, $unset: { myValues: 1} });
}
Since my collection is very large, it takes really long to execute.
You can consider using $out as an alternative, single-command solution. It can be used to replace existing collection with the output of an aggregation. Knowing that you can write following aggregation pipeline:
db.myCollection.aggregate([
{
$replaceRoot: {
newRoot: {
$mergeObjects: [ "$$ROOT", "$myValues" ]
}
}
},
{
$project: {
myValues: 0
}
},
{
$out: "myCollection"
}
])
$replaceRoot allows you to promote an object which merges the old $$ROOT and myValues into root level.

Check if a value exists in array using aggregation

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/] } }

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