Create array with query MongoDb - arrays

I have this Collection
{
"_id" : ObjectId("55555555ffffff000010200a"),
"name" : "foo"
}
{
"_id" : ObjectId("55555555ffffff000010200e"),
"name" : "bar"
}
{
"_id" : ObjectId("55555555ffffff000010200f"),
"name" : "baz"
}
{
"_id" : ObjectId("55555555ffffff000010200b"),
"name" : "biz"
}
and I want an array ids
I did this
db.mycollection.find({}, {_id: 1})
and return
{
"_id" : ObjectId("55555555ffffff000010200a")
}
{
"_id" : ObjectId("55555555ffffff000010200e")
}
{
"_id" : ObjectId("55555555ffffff000010200f")
}
{
"_id" : ObjectId("55555555ffffff000010200b")
}
{
"_id" : ObjectId("55555555ffffff000010200c")
}
{
"_id" : ObjectId("55555555ffffff0000103111")
}
Can I have an array?
id['55555555ffffff0000103111','55555555ffffff0000103111','555555555ffffff0000103111','55555555ffffff0000103111']

Option 1: If an array of subdocuments is acceptable, you can just append .toArray() to the find query.
> db.test.find({}, {_id:1}).toArray()
[
{
"_id" : ObjectId("53270b12d111b9bf595f4270")
},
{
"_id" : ObjectId("53270b14d111b9bf595f4271")
},
{
"_id" : ObjectId("53270b16d111b9bf595f4272")
}
]
Option 2: Another option is to use the aggregation framework.
> db.test.aggregate([{$group:{_id:null, ids:{$push:"$_id"}}}, {$project:{_id:0, ids:1}}])
{
"result" : [
{
"ids" : [
ObjectId("53270b12d111b9bf595f4270"),
ObjectId("53270b14d111b9bf595f4271"),
ObjectId("53270b16d111b9bf595f4272")
]
}
],
"ok" : 1
}
Option 3: Or you can use forEach in the shell like this:
> var myIds = new Array()
> db.test.find({},{_id:1}).forEach(function(myDoc){myIds.push(myDoc._id.str)})
> myIds
[
"53270b12d111b9bf595f4270",
"53270b14d111b9bf595f4271",
"53270b16d111b9bf595f4272"
]

Use distinct to turn a single column into an array:
db.mycollection.distinct('_id', function(err, list){
//list is an array of ObjectId
});

Related

Update value of key in Object in nested array of objects in MongoDB

I am trying to update data of "array1.array2._id": ObjectId("627a6fab60dc3c523b396af1") and Set Name to John But it's updating in all array2's first element's name to John.
db.getCollection('tests')
.updateOne({ "array1.array2._id": ObjectId("627a6fab60dc3c523b396af1") },{ $set: { "array1.$[].array2.$.name" : "John" } })
{
"_id" : ObjectId("627a6fab60dc3c523b396aec"),
"array1" : [
{
"array2" : [
{
"_id" : ObjectId("627a6fab60dc3c523b396af1"),
"name" : "test"
},
{
"_id" : ObjectId("627a6fab60dc3c523b396af2"),
"name" : "ABC"
}
],
"_id" : ObjectId("627a6fab60dc3c523b396aed")
},
{
"array2" : [
{
"_id" : ObjectId("627a6fab60dc3c523b396af3"),
"name" : "XYZ"
},
{
"_id" : ObjectId("627a6fab60dc3c523b396af4"),
"name" : "Testing"
}
],
"_id" : ObjectId("627a6fab60dc3c523b396aee")
}
]
}
Based on this great answer by #R2D2, you can do:
db.collection.update({
"array1.array2._id": ObjectId("627a6fab60dc3c523b396af1")
},
{
$set: {
"array1.$[].array2.$[y].name": "John"
}
},
{
arrayFilters: [
{
"y._id": ObjectId("627a6fab60dc3c523b396af1")
}
]
})
As you can see on this playground example

Getting Specific Array Element - Meteor Mongodb

I have this structure
{
"_id" : "EbtLm2Nmb79WWryEr",
"notificationByUsers" : {
"all" : [
{
"account_id" : "X5PjY66JAwgoxDb4L",
"date" : ISODate("2016-07-27T13:48:17.154Z"),
"value" : null
},
{
"account_id" : "2C2FKXaKtmeRMNT3E",
"date" : ISODate("2016-07-27T13:53:10.296Z"),
"value" : "Instant"
},
{
"account_id" : "6Np35oj63cavF4RHs",
"date" : ISODate("2016-07-28T07:18:22.696Z"),
"value" : "Instant"
}
]
}
}
and i am querying
db.Collection.findOne({_id: EbtLm2Nmb79WWryEr, 'notificationByUsers.all':{$elemMatch:{account_id: "2C2FKXaKtmeRMNT3E"}}}, {_id:0, 'notificationByUsers.all.$': 1})
it returns in roboMongo
{
"notificationByUsers" : {
"all" : [
{
"account_id" : "2C2FKXaKtmeRMNT3E",
"date" : ISODate("2016-07-27T13:53:10.296Z"),
"value" : "Instant"
}
]
}
But in Meteor it returns all array elements with this query. I want the result with specific array element as working in robomongo.
You can do this using fields projection, like:
MyCollection.findOne({},{ fields : {_id:0, 'notificationByUsers.all':1}});
This will return object like :
{
"notificationByUsers" : {
"all" : [
{
"account_id" : "2C2FKXaKtmeRMNT3E",
"date" : ISODate("2016-07-27T13:53:10.296Z"),
"value" : "Instant"
}
]
}

In MongoDB, how do I update a field with the value of an element inside an array?

I have data in one MongoDb table that I need copied to another MongoDb table. The first table has a field with different elements (see examples below) which I know how to work with. The second table, however, has a field with an array that is itself made up of different elements. How do I reference the values in the array?
I've tried field.array[0].element and field.array.0.element, but neither of those work.
If there's anyone that could explain how to do this today, I'd appreciate it. The client wants this done by the end of the day. I'm stuck and am about ready to result to copying and pasting data. Thanks!
Here's table1. Notice that "won" is empty; I'm trying to fill it:
{
"_id" : ObjectId("5733835a836265135854b7dd"),
"won" : {
}
}
{
"_id" : ObjectId("5733835a836265135854b7de"),
"won" : {
}
}
{
"_id" : ObjectId("5733835a836265135854b7df"),
"won" : {
}
}
Here's table2. I'm trying to get to the values for the elements userId and screenName:
{
"_id" : ObjectId("5733835a836265135854b7dd"),
"auction": ObjectId("5733833a49841cdd4eb0eef5",
"lead" : {
"bid" : NumberInt(481),
"bidders" : [
{
"userId" : ObjectId("5514d167ac52b1df65e03b4d"),
"screenName" : "mdoed",
}
]
}
}
{
"_id" : ObjectId("5733835a836265135854b7de"),
"auction": ObjectId("5733833a49841cdd4eb0eef5",
"lead" : {
"bid" : NumberInt(481),
"bidders" : [
{
"userId" : ObjectId("5514d167ac52b1df65e03b4e"),
"screenName" : "mdoed",
}
]
}
}
{
"_id" : ObjectId("5733835a836265135854b7df"),
"auction": ObjectId("5733833a49841cdd4eb0eef5",
"lead" : {
"bid" : NumberInt(481),
"bidders" : [
{
"userId" : ObjectId("5514d167ac52b1df65e03b4f"),
"screenName" : "mdoed",
}
]
}
}
Here's what table1 should look like after the update:
{
"_id" : ObjectId("5733835a836265135854b7dd"),
"won" : {
"bid" : NumberInt(481),
"userId" : ObjectId("5514d167ac52b1df65e03b4d"),
"screenName" : "mdoed"
}
}
{
"_id" : ObjectId("5733835a836265135854b7de"),
"won" : {
"bid" : NumberInt(481),
"userId" : ObjectId("5514d167ac52b1df65e03b4e"),
"screenName" : "mdoed",
}
}
{
"_id" : ObjectId("5733835a836265135854b7df"),
"won" : {
"bid" : NumberInt(481),
"userId" : ObjectId("5514d167ac52b1df65e03b4f"),
"screenName" : "mdoed",
}
}
Here's the query I've tried:
var newActiveProperties = db.table2.find({"auction": ObjectId("5733833a49841cdd4eb0eef5")}).toArray();
newActiveProperties.forEach(function(doc) {
db.table1.update(
{ "_id": doc._id, },
{ "$set": { "won.bid": doc.lead.bid, "won.userId": doc.lead.bidders[0].userId, "won.screenName": doc.lead.bidders[0].screenName
}
},
{ multi: true }
);
});
I suspect that the syntax doc.lead.bidders[0].userId is wrong, but I'm not sure what the correct syntax is.

Why I can't get the full document form array?

I have this document in stored in my collection:
{ "_id" : ObjectId("5707b95b8415b224a48a0b2d"),
"companyId" : ObjectId("570269639caabe24e4e4043e"),
"descriptions" : [
{ "id" : ObjectId("5707b95b8415b224a48a0b2a"), "description" : "test" },
{ "id" : ObjectId("570cd8164fff3a20f88c0dc9"), "description" : "test1" },
{ "id" : ObjectId("570ce6ba4fff3a052c8c570f"), "description" : "etr" },
{ "id" : ObjectId("570cf1b64fff3a1a14d71716"), "description" : "43" },
{ "id" : ObjectId("570cf1b64fff3a1a14d71717"), "description" : "43" },
{ "id" : ObjectId("570cf1b64fff3a1a14d71719"), "description" : "345" }
],
"options" : [
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a"), "description" : "test" },
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a"), "description" : "test1" }
]
}
Now I'm trying to get the objects from the options array that are matching the descriptionId and here is how I'm doing it
db.CustomFields.find({companyId: ObjectId("570269639caabe24e4e4043e")},{"options.descriptionId": ObjectId("5707b95b8415b224a48a0b2a")})
But the result contains only the descriptionId - the description property is missing.
here is how the result looks like:
{ "_id" : ObjectId("5707b95b8415b224a48a0b2d"),
"options" : [
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a") },
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a") }
]
}
Why my query is not returning the full document from the array, but only a part of it? Can you give me a push?
EDIT
This is what I'm expecting to get from the query
{ "_id" : ObjectId("5707b95b8415b224a48a0b2d"),
"options" : [
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a", "description" : "test") },
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a", "description" : "test1") }
]
}
You need to include the other query with "options.descriptionId" together with the companyId query and use projection to return just the array you want.
The following shows this:
db.customFields.find(
{
"companyId": ObjectId("570269639caabe24e4e4043e"),
"options.descriptionId": ObjectId("5707b95b8415b224a48a0b2a")
},
{ "options": 1 }
);
Output
{
"_id" : ObjectId("5707b95b8415b224a48a0b2d"),
"options" : [
{
"descriptionId" : ObjectId("5707b95b8415b224a48a0b2a"),
"description" : "test"
},
{
"descriptionId" : ObjectId("5707b95b8415b224a48a0b2a"),
"description" : "test1"
}
]
}
Try this
db.CustomFields.find({companyId: ObjectId("570269639caabe24e4e4043e"),"options.descriptionId": ObjectId("5707b95b8415b224a48a0b2a")})

Get Multiple Objects From Array in different Documents MongoDb

My collection coll is
/* 1 */
{
"_id" : ObjectId("566121aa4b88d840eb7d1c50"),
"batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"),
"array" : [
{
"id" : 1
},
{
"id" : 2
},
{
"id" : 3
},
{
"id" : 4
}
]
}
/* 2 */
{
"_id" : ObjectId("5661224a4b88d840eb7d1c51"),
"batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"),
"array" : [
{
"id" : 1
},
{
"id" : 7
},
{
"id" : 3
},
{
"id" : 5
}
]
}
what i need is to pull objects in array 'array' where
batchCourseId = ObjectId("566122ab94b792fbdf81bcf3")
and 2<array.id<=5
expected output is
/* 1 */
{
"_id" : ObjectId("566121aa4b88d840eb7d1c50"),
"array" : [
{
"id" : 3
},
{
"id" : 4
}
]
}
/* 2 */
{
"_id" : ObjectId("5661224a4b88d840eb7d1c51"),
"array" : [
{
"id" : 3
},
{
"id" : 5
}
]
}
already tried
db.coll.find({"batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3")},
{ array: { $elemMatch: { id: { $gt: 2,$lte: 5} } } })
the output is like
/* 1 */
{
"_id" : ObjectId("566121aa4b88d840eb7d1c50"),
"array" : [
{
"id" : 3
}
]
}
/* 2 */
{
"_id" : ObjectId("5661224a4b88d840eb7d1c51"),
"array" : [
{
"id" : 3
}
]
}
close but only the first matching object in array is in result
FYI this only a sample set of data the original data is more complex and big in count
so pls let me know the best practice to do this, performance is also important
thanks in advance
You can use aggregation for achieving the same. A sample is shown below:
db.coll.aggregate(
{$match: {"batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3")}},
{$unwind: '$array'},
{$match: {'array.id': { $gt: 2,$lte: 5}}},
{$group: {_id: '$_id', array: {$push : '$array'}}}
)
Result:
{ "_id" : ObjectId("5661224a4b88d840eb7d1c51"), "array" : [ { "id" : 3 }, { "id" : 5 } ] }
{ "_id" : ObjectId("566121aa4b88d840eb7d1c50"), "array" : [ { "id" : 3 }, { "id" : 4 } ] }
In MongoDB aggregation $unwind creates Cartesian_product problem so in large data set is good way to avoid $unwind.
Let's check with your example if you use $unwind in aggregation then result looks like this
db.collectionName.aggregate([
{ "$match": { "batchCourseId": ObjectId("566122ab94b792fbdf81bcf3") }},
{ "$unwind": "$array" }
])
so result of above query is :
{ "_id" : ObjectId("566121aa4b88d840eb7d1c50"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 1 } }
{ "_id" : ObjectId("566121aa4b88d840eb7d1c50"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 2 } }
{ "_id" : ObjectId("566121aa4b88d840eb7d1c50"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 3 } }
{ "_id" : ObjectId("566121aa4b88d840eb7d1c50"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 4 } }
{ "_id" : ObjectId("5661224a4b88d840eb7d1c51"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 1 } }
{ "_id" : ObjectId("5661224a4b88d840eb7d1c51"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 7 } }
{ "_id" : ObjectId("5661224a4b88d840eb7d1c51"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 3 } }
{ "_id" : ObjectId("5661224a4b88d840eb7d1c51"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 5 } }
this create multiple documents and in large documents in collections it slow the performance and increase processing time.
Instead of $unwind use $map in aggregation with aggregation-set operator and the query is as below :
db.collection.aggregate([{
"$match": {
"batchCourseId": ObjectId("566122ab94b792fbdf81bcf3")
}
}, {
"$project": {
"array": {
"$setDifference": [{
"$map": {
"input": "$array",
"as": "el",
"in": {
"$cond": {
"if": {
"$and": [{
"$gt": ["$$el.id", 2]
}, {
"$lte": ["$$el.id", 5]
}]
},
"then": "$$el",
"else": false
}
}
}
},
[false]
]
}
}
}])

Resources