MongoDB Array Data removing - arrays

This is the data I have, I want to remove the the array of that particular monitorId when it matches the User Id
{
"_id" : ObjectId("5afd8d562b2de0034953fdae"),
"isActiveEnabled" : true,
"isFrEnabled" : null,
"isDriveEnabled" : true,
"organization" : "5747f009544abb2ecbccae5f",
"monitorList" : [
{
"timeFailSmsAlert" : false,
"emailAlert" : true,
"alcoholSmsAlert" : true,
"failEmailAlert" : false,
"displayName" : "t",est
"username" : "test",
"monitorId" : "5748fcb6c9e3deeb30d8c74f",
"organization" : "5747f009544abb2ecbccae5f"
}
],
"userId" : "5afd8d542b2de0034953fdac"
}
This is my query:
db.getCollection("userconfigs").update({'userId':'5b2f276ea93966a93474006e'},{$pull:{'monitorlist':{'monitorId':'5b30a4002dea1a0fd6597b79'}}})
This is the output I got , Basically I want to remove
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

Changing the variable from monitorlist to monitorList solved the issue, thanks.

Related

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

Mongodb not using index for array of objects

I am trying to fetch few documents in a collection, by making a find query on array of nested objects. Nested objects are indexed but find query is not using the index to fetch documents.
Here is the structure of a document.
"_id" : ObjectId("5bc6498c1ec4062983c4f4ef"),
"appId" : ObjectId("5bbc775036021bea06d9bbc2"),
"status" : "active",
"segmentations" : [
{
"name" : "ch-1",
"values" : [
'true'
],
"type" : "string"
},
{
"name" : "browerInfo",
"values" : [
"Firefox"
],
"version" : [
"62.0"
],
"majorVersion" : [
"62"
],
"type" : "string"
},
{
"name" : "OS",
"values" : [
"Ubuntu"
],
"type" : "string"
},
{
"name" : "lastVisitTime",
"values" : [
1539721615231.0
],
"type" : "number"
}
]
}
Here are the index fields.
{
"v" : 2,
"key" : {
"appId" : 1,
"status" : 1,
"segmentations.name" : 1,
"segmentations.values" : 1
},
"name" : "SEGMENT_INDEX",
"ns" : "test.Collname"
}
below is the find find query i was executing
db.Collname.find({
appId: ObjectId("5c6a8ef544ff62c73bdb98fc"),
"segmentations.name": 'ch-1',
'segmentations.values': 'true',
status: 'active'
}, {})
I tried to get the query execution information using
<above query>.explain("executionStats")
The result is
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.Collname",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"appId" : {
"$eq" : ObjectId("5c6a8ef544ff62c73bdb98fc")
}
},
{
"segmentations.name" : {
"$eq" : "ch-1"
}
},
{
"segmentations.values" : {
"$eq" : "true"
}
},
{
"status" : {
"$eq" : "active"
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"segmentations.values" : {
"$eq" : "true"
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"appId" : 1.0,
"status" : 1.0,
"segmentations.name" : 1.0,
"segmentations.values" : 1.0
},
"indexName" : "SEGMENT_INDEX",
"isMultiKey" : true,
"multiKeyPaths" : {
"appId" : [],
"status" : [],
"segmentations.name" : [
"segmentations"
],
"segmentations.values" : [
"segmentations",
"segmentations.values"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"appId" : [
"[ObjectId('5c6a8ef544ff62c73bdb98fc'), ObjectId('5c6a8ef544ff62c73bdb98fc')]"
],
"status" : [
"[\"active\", \"active\"]"
],
"segmentations.name" : [
"[\"ch-1\", \"ch-1\"]"
],
"segmentations.values" : [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans" : []
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 28176,
"executionTimeMillis" : 72,
"totalKeysExamined" : 28176,
"totalDocsExamined" : 28176,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"segmentations.values" : {
"$eq" : "true"
}
},
"nReturned" : 28176,
"executionTimeMillisEstimate" : 70,
"works" : 28177,
"advanced" : 28176,
"needTime" : 0,
"needYield" : 0,
"saveState" : 220,
"restoreState" : 220,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 28176,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 28176,
"executionTimeMillisEstimate" : 10,
"works" : 28177,
"advanced" : 28176,
"needTime" : 0,
"needYield" : 0,
"saveState" : 220,
"restoreState" : 220,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"appId" : 1.0,
"status" : 1.0,
"segmentations.name" : 1.0,
"segmentations.values" : 1.0
},
"indexName" : "SEGMENT_INDEX",
"isMultiKey" : true,
"multiKeyPaths" : {
"appId" : [],
"status" : [],
"segmentations.name" : [
"segmentations"
],
"segmentations.values" : [
"segmentations",
"segmentations.values"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"appId" : [
"[ObjectId('5c6a8ef544ff62c73bdb98fc'), ObjectId('5c6a8ef544ff62c73bdb98fc')]"
],
"status" : [
"[\"active\", \"active\"]"
],
"segmentations.name" : [
"[\"ch-1\", \"ch-1\"]"
],
"segmentations.values" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 28176,
"seeks" : 1,
"dupsTested" : 28176,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {
"host" : "sys3029",
"port" : 27017,
"version" : "4.0.9",
"gitVersion" : "fc525e2d9b0e4bceff5c2201457e564362909765"
},
"ok" : 1.0
}
I could see from executionStats that "segmentations.values" field is not used in "IXSCAN" stage. And there is an extra filter stage on "segmentations.values". IXSCAN stage took just 10ms, where as FILTER stage took 50ms.
I couldn't understand why the field is not included in IXSCAN stage. My collection has around 3.2 Million documents and because of this issue query execution time is very high than expected.
Please help me fix the issue.
Thank you in advance.
Please suggest me If I need to change my database structure,
If it is not possible in mongodb,you can suggest some other database which supports above operations.
The following query will use your index for both of your array fields:
.find({
appId: ObjectId("5c6a8ef544ff62c73bdb98fc"),
segmentations:{$elemMatch:{name: 'ch-1',values: 'true'}},
status: 'active'
}, {})
If you are not using $elemMatch, MongoDB can compound the bounds for the array item keys with either the bounds for "segmentations.name" or the bounds for "segmentations.values", but not both.
In order to compound the bounds for "segmentations.name" with the bounds for "segmentations.values", the query must use $elemMatch.
To compound together the bounds for index keys from the same array:
the index keys must share the same field path up to but excluding the
field names,
and the query must specify predicates on the fields
using $elemMatch on that path.
I suggest you to read mongodb docs about multikey-index-bounds and also about $elemMatch.

Mongodb replication (secondary server)

I set up a master-slave replication of MongoDB by using 2 servers. The problem is I always going to assign rs.slaveOk() in slave server after inserting data in master. I want to automatically synced(no need to rs.slaveOk()) in secondary! What configurations should I need to change? Thanks !
This is my rs.conf()for master-slave replication!
> rs2:PRIMARY> rs.conf() { "_id" : "rs2", "version" : 3,
> "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0,
> "host" : "192.168.56.104:27017", "arbiterOnly" : false,
> "buildIndexes" : true, "hidden" : false, "priority" : 1,
> "tags" : {
> }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "192.168.56.106:27017", "arbiterOnly" :
> false, "buildIndexes" : true, "hidden" : false, "priority" :
> 0, "tags" : {
> }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true,
> "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10,
> "electionTimeoutMillis" : 10000, "getLastErrorModes" : {
> }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("5a1e37704f3b7025eccaa874") } }
You can create a file /etc/mongorc.js and add rs.slaveOk() there. The file is being evaluated on each shell startup.
You can have a look here for more clarification.
Or, another way is to start mongo with the following command:
>mongo --port 27012 --eval "rs.slaveOk()" --shell
slaveOk() is only valid for that console session that it was executed in, so you would need to pass in a script or stay connected to the console with the --shell arguments.

mongodb how to insert the sub document one by one

i have a document in mongodb like this:
db.full_stock_order_flow.find({skuId:"a19011100abc0084",stockGroup:"ABC_01"})
result:
{
"_id" : ObjectId("59bb5698c37fe6085b36f7d5"),
"skuId" : "a19011100abc0084",
"stockGroup" : "ABC_01",
"orderflowJsonEncode" : [
{
"calcDate" : "2016-01-28",
"acbQty" : NumberInt(0),
"abcQty" : NumberInt(30),
"stockQty" : NumberInt(0),
"isActiveDay" : true,
"outQtyWhenFullStockQty" : NumberInt(30)
},
{
"calcDate" : "2016-01-29",
"acbQty" : NumberInt(0),
"abcQty" : NumberInt(13),
"stockQty" : NumberInt(53),
"isActiveDay" : true,
"outQtyWhenFullStockQty" : NumberInt(13)
}
],
"createdOn" : "2017-09-05 12:27:04",
"createdBy" : "helloworld"
}
and i want to find the sub document and insert it the other collectin with parent Document like change 2 document without sub document in the other document:
{
"_id" : ObjectId("59bb5698c37kk6085b36f7d5"),
"skuId" : "a19011100abc0084",
"stockGroup" : "ABC_01",
"calcDate" : "2016-01-28",
"acbQty" : NumberInt(0),
"abcQty" : NumberInt(30),
"stockQty" : NumberInt(0),
"isActiveDay" : true,
"outQtyWhenFullStockQty" : NumberInt(30),
"createdOn" : "2017-09-05 12:27:04",
"createdBy" : "helloworld"
}
{
"_id" : ObjectId("59bb5698c37kk6085b36f7d5"),
"skuId" : "a19011100abc0084",
"stockGroup" : "ABC_01",
"calcDate" : "2016-01-29",
"acbQty" : NumberInt(0),
"abcQty" : NumberInt(13),
"stockQty" : NumberInt(53),
"isActiveDay" : true,
"outQtyWhenFullStockQty" : NumberInt(13),
"createdOn" : "2017-09-05 12:27:04",
"createdBy" : "helloworld"
}
what can i do?
i use this :
var record=db.full_stock_order_flow.find({skuId:"a19011100abc0084",stockGroup:"US_01"});
var arr=record.orderflowJsonEncode;
arr.forEach(
function(item){
db.tt123.insert({"skuId": record.skuId,"stockGroup": record.stockGroup , "orderflowJsonEncode":item});
}
)

how to get length in angularjs because of length my second loop not run

i have below code in angularjs but when i want length of my array 0 position its show undefined please check below code that's why my second loop does not run. in angular how to solve this type of problem anyone help me please
this.current_engineer = response.data;
var current_schedules = this.current.schedule;
console.log(current_schedules);
console.log(current_schedules.length);
console.log(current_schedules[0].length);
if (angular.isArray(current_schedules)) {
for (var j = 0; j < current_schedules.length; j++) {
for (var i = 0; i < current_schedules[j].length; i++) //this loop does not run because of length how to get length
{
console.log(current_schedules[j][i].title);
}
}
}
///------------Mongodb Database-----------------------
"schedule" : [
[
{
"_id" : ObjectId("58f76aa9be4d311a78f24f78"),
"sch_end" : ISODate("2017-04-21T00:00:00.000Z"),
"sch_start" : ISODate("2017-04-21T00:00:00.000Z"),
"available" : false,
"title" : "test3"
},
{
"_id" : ObjectId("58f76aa9be4d311a78f24f77"),
"sch_end" : ISODate("2017-04-22T00:00:00.000Z"),
"sch_start" : ISODate("2017-04-22T00:00:00.000Z"),
"available" : false,
"title" : "test4"
},
{
"_id" : ObjectId("58f76aa9be4d311a78f24f76"),
"sch_end" : ISODate("2017-04-23T00:00:00.000Z"),
"sch_start" : ISODate("2017-04-23T00:00:00.000Z"),
"available" : false,
"title" : "test6"
}
],
[
{
"_id" : ObjectId("58f76aa9be4d311a78f24f78"),
"sch_end" : ISODate("2017-04-24T00:00:00.000Z"),
"sch_start" : ISODate("2017-04-24T00:00:00.000Z"),
"available" : false,
"title" : "test9"
},
{
"_id" : ObjectId("58f76aa9be4d311a78f24f77"),
"sch_end" : ISODate("2017-04-25T00:00:00.000Z"),
"sch_start" : ISODate("2017-04-25T00:00:00.000Z"),
"available" : false,
"title" : "test10"
},
{
"_id" : ObjectId("58f76aa9be4d311a78f24f76"),
"sch_end" : ISODate("2017-04-27T00:00:00.000Z"),
"sch_start" : ISODate("2017-04-27T00:00:00.000Z"),
"available" : false,
"title" : "test11"
}
]
],
Your property's value at current_schedules[0] is a js object and js object doesn't have any property called length. You could use something like Object.keys(current_schedules[0]).length.
Note: For IE9+ and all other modern ES5+ capable browsers.

Resources