unable to use $pullAll - arrays

I have a collection which contains the documents as shown below
{
"_id" : ObjectId("56d92901f9d573cc1c1fb8bb"),
"busEntryExitInformation" : {
"dateTime" : ISODate("2016-03-04T06:19:45.914+0000"),
"busEntryExitEvent" : [
{
"plateNumber" : "ADFN3R2",
"direction" : "EXIT",
"routeNumber" : NumberInt(929),
"driverID" : "DId5",
"driverName" : "john",
"_id" : ObjectId("56d92901f9d573cc1c1fb8c0")
},
{
"plateNumber" : "ADFN3R4",
"direction" : "EXIT",
"routeNumber" : NumberInt(652),
"driverID" : "DId2",
"driverName" : "jack",
"_id" : ObjectId("56d92901f9d573cc1c1fb8bf")
},
{
"plateNumber" : "ADFN3R8",
"direction" : "EXIT",
"routeNumber" : NumberInt(500),
"driverID" : "DId5",
"driverName" : "john",
"_id" : ObjectId("56d92901f9d573cc1c1fb8be")
},
{
"plateNumber" : "ADFN3R7",
"direction" : "ENTRY",
"routeNumber" : NumberInt(500),
"driverID" : "DId3",
"driverName" : "mack",
"_id" : ObjectId("56d92901f9d573cc1c1fb8bd")
},
{
"plateNumber" : "ADFN3R2",
"direction" : "EXIT",
"routeNumber" : NumberInt(652),
"driverID" : "DId2",
"driverName" : "sandesh",
"_id" : ObjectId("56d92901f9d573cc1c1fb8bc")
}
],
"cameraIntrinsics" : {
"cameraFocalLength" : NumberInt(35),
"cameraAngle" : NumberInt(20),
"imageWidth" : "1920",
"imageHeight" : "1080",
"frameRate" : NumberInt(25)
},
"cameraExtrinsics" : {
"cameraId" : NumberInt(1),
"cameraName" : "Under Route-090 NorthboundBridge",
"cameraDirection" : "Towards Northbound Lanes",
"cameraLatitude" : 1.350228,
"cameraLongitude" : 103.984889,
"cameraHeight" : NumberInt(30)
}
},
"__v" : NumberInt(0)
}
}
where busEntryExitEvent is a array i am trying to remove the array elements where direction is exit across all the documents in the collection
result should contain all the documents with direction entry
{
"_id" : ObjectId("56d92901f9d573cc1c1fb8bb"),
"busEntryExitInformation" : {
"dateTime" : ISODate("2016-03-04T06:19:45.914+0000"),
"busEntryExitEvent" : [
{
"plateNumber" : "ADFN3R7",
"direction" : "ENTRY",
"routeNumber" : NumberInt(500),
"driverID" : "DId3",
"driverName" : "mack",
"_id" : ObjectId("56d92901f9d573cc1c1fb8bd")
}
],
"cameraIntrinsics" : {
"cameraFocalLength" : NumberInt(35),
"cameraAngle" : NumberInt(20),
"imageWidth" : "1920",
"imageHeight" : "1080",
"frameRate" : NumberInt(25)
},
"cameraExtrinsics" : {
"cameraId" : NumberInt(1),
"cameraName" : "Under Route-090 NorthboundBridge",
"cameraDirection" : "Towards Northbound Lanes",
"cameraLatitude" : 1.350228,
"cameraLongitude" : 103.984889,
"cameraHeight" : NumberInt(30)
}
},
"__v" : NumberInt(0)
}
}
i am trying to do like this
db.busEntryExitDoc.update(
{ $pull: { busEntryExitEvent: { "direction" : "EXIT"} } },
{ multi: false }
)
this has to be done to all the documents there is no where condition here how to do it please help

The MongoDB update() methods expects three arguments: db.collection.update(query, update, options). If you want to perform the update on all documents, just use an empty object as query:
db.busEntryExitDoc.update({},
{ $pull: { 'busEntryExitInformation.busEntryExitEvent' : {'direction' : "EXIT"} } },
{ multi: true }
);
Also, note the use of the dot notation to access the array field: you have to point the $pull operator to an array otherwise the operation fails. Finally, use { multi: true } as options since you want to update all the documents in your collection.

You are doing it wrong the first argument to .update() is the "query" argument which should be an empty document here.
db.busEntryExitDoc.update(
{},
{ $pull: { "busEntryExitInformation.busEntryExitEvent": { "direction": "EXIT" } } },
{ multi: true }
)
The same thing apply to the .updateMany() method
db.busEntryExitDoc.update(
{},
{ $pull: { "busEntryExitInformation.busEntryExitEvent": { "direction": "EXIT" } } },
)

Related

How can I specific array values as out as given below?

I was get an result of aggregate query from collection using $facet and $group aggregate but our development team does not satisfies with this result they are asked result must not be an objects given end
{
"_id" : ObjectId("6316e1b9a9ac1f9acceaf488"),
"status_counts" : [
{
"_id" : {
"status" : "Closed"
},
"count" : 59662.0
},
{
"_id" : {
"status" : "Open"
},
"count" : 695.0
},
{
"_id" : {
"status" : "Pending"
},
"count" : 4039.0
}
],
"Priority_counts" : [
{
"_id" : {
"Priority" : "Escalated"
},
"count" : 4722.0
},
{
"_id" : {
"Priority" : "Low"
},
"count" : 11.0
},
{
"_id" : {
"Priority" : "High"
},
"count" : 1.0
},
{
"_id" : {
"Priority" : "Medium"
},
"count" : 1.0
}
],
"assigned" : [
{
"_id" : true,
"count" : 4351.0
},
{
"_id" : false,
"count" : 383.0
}
],
"transfered" : [
{
"_id" : true,
"count" : 245.0
}
],
"cc" : [
{
"_id" : true,
"count" : 4.0
}
]
}
===================================================================================
From the above document expected output as below.. can anyone suggest me please..
{
"_id" : ObjectId("6316e1b9a9ac1f9acceaf488"),
"status_counts" : [
{
"status" : "Closed",
"count" : 59662.0
},
{
"status" : "Open"
"count" : 695.0
},
{
"status" : "Pending"
"count" : 4039.0
}
],
"Priority_counts" : [
{
"Priority" : "Escalated"
"count" : 4722.0
},
{
"Priority" : "Low"
"count" : 11.0
},
{
"Priority" : "High"
"count" : 1.0
},
{
"Priority" : "Medium"
"count" : 1.0
}
],
"assigned" : [
{
"_id" : true,
"count" : 4351.0
},
{
"_id" : false,
"count" : 383.0
}
],
"transfered" : [
{
"_id" : true,
"count" : 245.0
}
],
"cc" : [
{
"_id" : true,
"count" : 4.0
}
]
}

How to make new array from another array during aggregation?

I have following document:
{
"subscriptionIds" : [
ObjectId("60c312c6dbb5a49fbbf560ea")
],
"gps" : {
"type" : "Point",
"coordinates" : [
23.942706,
54.932539
]
},
"online" : false,
"suspended" : false,
"hwModel" : "",
"fw" : "",
"lastSeen" : ISODate("2021-06-16T04:43:36.682Z"),
"lastSimRequest" : ISODate("2021-06-16T04:34:59.749Z"),
"lastLocation" : "LT",
"lastLocationType" : "gps",
"createdAt" : ISODate("2021-05-20T10:37:16.025Z"),
"updatedAt" : ISODate("2021-06-11T07:37:56.981Z"),
"notes" : "",
"psk_seed" : "QTAebOeNP4nIs-JJSNNlkAQ78N_VaxOq98-_lQPCyZQ=",
"lastOnline" : ISODate("2021-06-15T08:01:59.886Z"),
"lastOffline" : ISODate("2021-06-16T04:43:36.682Z"),
"onlineReason" : "deviceOnlineStatusFromAC",
"offlineReason" : "deviceOfflineStatusTimeout",
"allocationSettings" : "dataplan",
"subscriptionDataplans" : [
{
"_id" : ObjectId("5fae82fc1224cc8d62b5bf17"),
"organizationId" : ObjectId("5dd63d1c1d042f3018e8374e"),
"organizationName" : "",
"name" : "Naujas plan Telia 75GB",
"enabled" : true,
"contractsId" : [
ObjectId("5e32847ab8013befcc14bb1b"),
ObjectId("5e32847ab8013befcc14bb1b")
],
"simQuota" : 0,
"periodQuota" : NumberLong(0),
"allocationRules" : null,
"createdAt" : ISODate("2020-11-13T12:58:36.650Z"),
"updatedAt" : ISODate("2021-06-14T08:08:28.728Z"),
"notes" : "",
"allowRoaming" : false,
"enablePriorityOrdering" : false,
"priorityOrdering" : ""
},
{
"_id" : ObjectId("5fcf25662b1c7d9bab8c1f7d"),
"organizationId" : ObjectId("5dd63d1c1d042f3018e8374e"),
"organizationName" : "",
"name" : "London test",
"enabled" : true,
"contractsId" : [
ObjectId("5e5dfea1efcf754767408eae")
],
"simQuota" : 0,
"periodQuota" : NumberLong(0),
"createdAt" : ISODate("2020-12-08T07:04:06.255Z"),
"updatedAt" : ISODate("2021-06-15T09:28:07.472Z"),
"notes" : "",
"allowRoaming" : true,
"enablePriorityOrdering" : false,
"priorityOrdering" : ""
}
],
}
Is there a way to make following array using "_id" and "allowRoaming" fields:
"dataplanRoaming": [
{
"_id" : ObjectId("5fae82fc1224cc8d62b5bf17"),
"allowRoaming" : false,
},
{
"_id" : ObjectId("5fcf25662b1c7d9bab8c1f7d"),
"allowRoaming" : true,
}
]
My best result was, I tried using project, addFields etc still can't get structure which I want. Rest of query works just fine just missing this part
"dataplanRoaming" : [
[
false,
true
],
[
ObjectId("5fae82fc1224cc8d62b5bf17"),
ObjectId("5fcf25662b1c7d9bab8c1f7d")
]
],
I hoped that {$addFields:{dataplanRoaming:["$subscriptionDataplans.allowRoaming", "$subscriptionDataplans._id"]}},
would give me wanted result it just made array with _id and allowRoaming as separates fields?
Is there a way to create my wanted result using aggregation etc?
$map to iterate loop of subscriptionDataplans and return needed feidls
db.collection.aggregate([
{
$addFields: {
dataplanRoaming: {
$map: {
input: "$subscriptionDataplans",
in: {
_id: "$$this._id",
allowRoaming: "$$this.allowRoaming"
}
}
}
}
}
])
Playground

Mongo matching only where first element of array has certain field value

I have a query below that extracts a couple of values from a large nested document. It tells me the user id and the first item name for each order.
This works fine, however I want it to only return the record where the first item's name is not null and is not blank. I can't figure out how to add a second query to the $match operator below to achieve this
db.getCollection('Orders').aggregate
([
{ $match : { "Items.1" : { $exists : true }}, ???},
{ $project: {
_id:0,
'UserId': '$User.EntityId',
'ItemName': {$arrayElemAt: ['$Items.Details.ItemName', 0]}
}
}
]);
Edited to show sample document
{
"_id" : "order-666156",
"State" : "ValidationFailed",
"LastUpdated" : {
"DateTime" : ISODate("2017-09-26T08:54:16.241Z"),
"Ticks" : NumberLong(636420128562417375)
},
"SourceOrderId" : "666156",
"User" : {
"EntityId" : NumberLong(34450),
"Name" : "Bill Baker",
"Country" : "United States",
"Region" : "North America",
"CountryISOCode" : "US",
},
"Region" : null,
"Currency" : null,
"Items" : [
{
"ClientOrderId" : "18740113",
"OrigClientOrderId" : "18740113",
"Quantity" : NumberDecimal("7487.0"),
"TransactDateTime" : {
"DateTime" : Date(-62135596800000),
"Ticks" : NumberLong(0)
},
"Text" : null,
"LocateRequired" : false,
"Details" : {
"ItemName" : "Test Item 1",
"ItemCost" : 1495.20
}
},
{
"ClientOrderId" : "18740116",
"OrigClientOrderId" : "18740116",
"Quantity" : NumberDecimal("241.0"),
"TransactDateTime" : {
"DateTime" : Date(-62135596800000),
"Ticks" : NumberLong(0)
},
"Text" : null,
"LocateRequired" : false,
"Details" : {
"ItemName" : "Test Item 2",
"ItemCost" : 2152.64
}
}
]
}
You need to add the two conditions to your existing $match (not null and not blank) to check the Items as:
$match : { "Items.1" : { $exists : true, "$ne": null,"$ne":""}
If you want to check the element Items[0].Details.ItemName you can doing using the operator $and
{ $match : {
$and: [
{"Items.1" : { $exists : true }},
{"Items.Details.ItemName" : { $ne : null}},
{"Items.Details.ItemName" : { $ne : ""}},
]
}},

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")})

how return array objects in find mongodb hierarchy data json

How to return the array object "items" as follows database db.customers using mongodb
I have problems when going to another page because the query returns me a single object, not the object array items
Customer
.find({user: req.user})
.filter(filter)
.order(sort)
.map(function(doc){
return doc.get('videos').items;
})
.page(pagination, function(err, customers){
if(err){
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else{
res.jsonp(customers);
}
});
below the json structure where is the array items:
{
"_id" : ObjectId("54de533a9585180c24f42887"),
"videos" : {
"items" : [{
"snippet" : {
"liveBroadcastContent" : "none",
"thumbnails" : {
"default" : {
"height" : 90,
"width" : 120,
"url" : "https://i.ytimg.com/vi/xLWBnEQQiIA/default.jpg"
}
},
"description" : "yea foodporn",
"title" : "#foodporn",
"channelId" : "UC7FN6ofleSjbqwWxt-FNDWQ",
"publishedAt" : "2015-01-16T03:21:35.000Z"
},
"id" : {
"videoId" : "xLWBnEQQiIA",
"kind" : "youtube#video"
},
"etag" : "\"k1sYjErg4tK7WaQQxvJkW5fVrfg/M4htbh5SyAjA8ul83DhltycTU6E\"",
"kind" : "youtube#searchResult"
}, {
"snippet" : {
"liveBroadcastContent" : "none",
"thumbnails" : {
"default" : {
"height" : 90,
"width" : 120,
"url" : "https://i.ytimg.com/vi/v-1_pxe37-s/default.jpg"
}
},
"description" : "food porn delicius",
"title" : "#foodporn b",
"channelId" : "UC7FN6ofleSjbqwWxt-FNDWQ",
"publishedAt" : "2015-01-16T03:14:15.000Z"
},
"id" : {
"videoId" : "v-1_pxe37-s",
"kind" : "youtube#video"
},
"etag" : "\"k1sYjErg4tK7WaQQxvJkW5fVrfg/0SfjWbYvc4M7hdvXUFAsnZF-3vU\"",
"kind" : "youtube#searchResult"
}, {
"snippet" : {
"liveBroadcastContent" : "none",
"thumbnails" : {
"default" : {
"height" : 90,
"width" : 120,
"url" : "https://i.ytimg.com/vi/DMfa1u8_3B8/default.jpg"
}
},
"description" : "o yeah foos porn",
"title" : "food porn a",
"channelId" : "UC7FN6ofleSjbqwWxt-FNDWQ",
"publishedAt" : "2015-01-16T03:03:09.000Z"
},
"id" : {
"videoId" : "DMfa1u8_3B8",
"kind" : "youtube#video"
},
"etag" : "\"k1sYjErg4tK7WaQQxvJkW5fVrfg/ghsCGgrP3VQw6kH3v2LijEPPUv8\"",
"kind" : "youtube#searchResult"
}],
"pageInfo" : {
"resultsPerPage" : 50,
"totalResults" : 30
},
"nextPageToken" : "Cib3_b-JoP____96V0dSU3BHYjlCRQD_Af_-eldHUlNwR2I5QkUAARAeIbnxc1PpBEevOQAAAABfdkACSAFQAFoLCSuH7BJBzCiDEAE=",
"etag" : "\"k1sYjErg4tK7WaQQxvJkW5fVrfg/WBVbC5oh7cdDE3IlyjlCZpMW7bQ\"",
"kind" : "youtube#searchListResponse"
},
"user" : ObjectId("54de0f96b4d42d90195f892e"),
"__v" : 0
}
"user" : ObjectId("54de0f96b4d42d90195f892e"),
"__v" : 0
}
Customer.find(...).map(function(doc){
return doc.get('videos').items;
})
This what you're looking for?
I think the call you're looking for is
db.customers.find({ "user" : "xxx" }, { "videos.items" : 1 })
See the projection docs for more information about how to return specific fields from documents in a query.

Resources