mongodb explain always returns millis as 0 - node.js

I am using the node.js mongodb native driver and I have a collection with a bunch of docs inside like:
{
name: "cat",
}
I have a query which I am trying to test the speed of:
collection.find({name: { $gt: 'ca', $lt: 'cb' } }).explain(function(err, docs){
console.log( docs );
});
But the milliseconds is always 0
{ cursor: 'BasicCursor',
isMultiKey: false,
n: 2,
nscannedObjects: 8,
nscanned: 8,
nscannedObjectsAllPlans: 8,
nscannedAllPlans: 8,
scanAndOrder: false,
indexOnly: false,
nYields: 0,
nChunkSkips: 0,
millis: 0,
allPlans:
[ { cursor: 'BasicCursor',
isMultiKey: false,
n: 2,
nscannedObjects: 8,
nscanned: 8,
scanAndOrder: false,
indexOnly: false,
nChunkSkips: 0 } ],
server: 'h003723.mongolab.com:33453',
filterSet: false,
stats:
{ type: 'COLLSCAN',
works: 10,
yields: 0,
unyields: 0,
invalidates: 0,
advanced: 2,
needTime: 7,
needFetch: 0,
isEOF: 1,
docsTested: 8,
children: [] } }
I cant seem to figure this out, and obviously I cant test the query like this, am I missing something?

Related

Great delay in response time in mongoose/mongoDB as api is called consecutively over time (irrespective of collection size)

I have a simple api using the mongoose find method, along with an _id filter:
Fee.find(
{
_id: feeDocId,
},
(err, fee) => {
if (fee[0] !== undefined) {
if (!err && fee[0] != '') {
res.json(fee[0]['gstno']);
}
}
}
);
The problem is that the response time of this api keeps on increasing exponentially with time (high latency).
API call
Latency (response time)
First time
68ms
Third time
22.75 sec
Fifth time
55.18 sec
Seventh time
1.6 minutes
ninth time
2.3 minutes
fired at api 2022-05-11T12:45:03+05:30 {}
response at api{
explainVersion: '1',
queryPlanner: {
namespace: 'myFirstDatabase.fee',
indexFilterSet: false,
parsedQuery: { _id: [Object] },
maxIndexedOrSolutionsReached: false,
maxIndexedAndSolutionsReached: false,
maxScansToExplodeReached: false,
winningPlan: { stage: 'IDHACK' },
rejectedPlans: []
},
executionStats: {
executionSuccess: true,
nReturned: 1,
executionTimeMillis: 1,
totalKeysExamined: 1,
totalDocsExamined: 1,
executionStages: {
stage: 'IDHACK',
nReturned: 1,
executionTimeMillisEstimate: 0,
works: 2,
advanced: 1,
needTime: 0,
needYield: 0,
saveState: 0,
restoreState: 0,
isEOF: 1,
keysExamined: 1,
docsExamined: 1
},
allPlansExecution: []
},
command: {
find: 'fee',
filter: { _id: new ObjectId("623042ce5fc371ac74c9b371") },
projection: {},
'$db': 'myFirstDatabase'
},
}
response at api 2022-05-11T12:48:41+05:30
API took this much time 217829
Any ideas as to why the latency increases progressively?
An important note: this high latency trend also applies to all other apis, and the trend repeats when I restart the server, ie, the response time increases over time since server start.The server being used is the M0 Sandbox (General) in MongoDB.
Thanks in advance..

How to update every document in collection based off another collection with Mongoose

I have a collection with a single document that contains many stats of different people.
It is structured like so:
// Stats list:
[{
id: .... ,
lastUpdated: ... ,
stats: {
Person1: {stat1: 0, stat2: 0, stat3: 0},
Person2: {stat1: 0, stat2: 0, stat3: 0},
...
Person100: {stat1: 0, stat2: 0, stat3: 0}
}
}]
These stats are updated every 24 hours.
Now I have a few hundred listings that contain a specific list of the people in the first collection.
// Listings:
[{
id: ...,
persons: {
Person1: {stat1: 0, stat2: 0, stat3: 0},
Person43: {stat1: 0, stat2: 0, stat3: 0}
}
}]
I want to be able to update all person stats in these listings compared to the persons in the stats section in the first collection I showed.
My logic is something along the lines of this:
await Listing.updateMany({}, { $set: { persons: { "some kind of query" } } });
But I am not sure how to most efficiently go about this.

How do I query a set of objects with an array of values in mongoose?

I have a schema like this
const rankSchema = new Schema(
{
rank: { type: Object, default: {} },
lastUpdated: { type: Date, default: Date.now() },
},
{ minimize: false }
);
And my database has an object 'rank' with many other objects inside of it like this.
rank: {
Person1: { Stat1: 2, Stat2: 0, Stat3: 0, Stat4: 2, Stat5: 4 },
Person2: { Stat1: 4, Stat2: 0, Stat3: 0, Stat4: 2, Stat5: 2 },
Person3: { Stat1: 1, Stat2: 0, Stat3: 0, Stat4: 2, Stat5: 1 },
Person4: { Stat1: 2, Stat2: 0, Stat3: 0, Stat4: 2, Stat5: 3 }
}
Now I have an array of strings that contains a few of these people
['Person1', 'Person2']
I want to be able to find all the person objects in that array and return their stats.
So essentially the final output after using the array of strings would be
Person1: { Stat1: 2, Stat2: 0, Stat3: 0, Stat4: 2, Stat5: 4 },
Person2: { Stat1: 4, Stat2: 0, Stat3: 0, Stat4: 2, Stat5: 2 }
I tried using $in and various different queries but nothing seems to work and I am stumped.
Thanks
You could use a combination of $objectToArray and $arrayToObject to filter your object by dynamic field names but if your parameters are known when you're building your query then it's easier to use regular .find() and apply projection:
db.collection.find({},{ "rank.Person1": 1, "rank.Person2": 1})
let input = ['Person1', 'Person2'];
let entries = input.map(p => ([`rank.${p}`, 1]))
let projection = Object.fromEntries(entries);
console.log(projection);
Mongo Playground

Write Array in nodeOpcua

Hiii, some body know how i can write Uint16Array in kepserver i got some error:
ConstantStatusCode {
_value: 2147483648,
_description: 'The value is bad but no specific reason is known.',
_name: 'Bad' } ]
i'm try this:
var valor = new Uint16Array([ 2, 23, 23, 12, 24, 3, 25, 3, 26, 3, 27, 3, 28, 1, 43690, 1, 1261, 0, 0, 0, 0, 0, 0, 0, 65535, 11 ])
nodeToWrite[0] = {
nodeId: resolveNodeId("ns=2;s=" + endereco[0].ADDRESS),
attributeId: opcua.AttributeIds.Value,
value: /new DataValue(/{ value: {/ Variant /
dataType: 5,
arrayType: 1,
value: valor,
}
}
}
const {AttributeIds, OPCUAClient, DataType, VariantArrayType} = require("node-opcua");
const endpointUrl = "opc.tcp://localhost:48010";
(async () => {
const client = OPCUAClient.create({ endpoint_must_exist: false});
await client.withSessionAsync(endpointUrl, async (session) => {
const arrayOfvalues = new Uint16Array([ 2, 23, 23, 12, 24, 3, 25, 3, 26, 3, 27, 3, 28, 1, 43690, 1, 1261, 0, 0, 0, 0, 0, 0, 0, 65535, 11 ]);
const nodeToWrite = {
nodeId: "ns=2;s=Demo.Static.Arrays.UInt16",
attributeId: AttributeIds.Value,
value: {
value: {
dataType: DataType.UInt16,
arrayType: VariantArrayType.Array,
value: arrayOfvalues,
}
}
}
const statusCode = await session.write(nodeToWrite);
console.log("write statusCode = ",statusCode.toString());
});
})();
As demonstrated above, writing a Array of Uint16 is ok when addressing node ns=2;s=Demo.Static.Arrays.UInt16 of UAServerCPP from Unified Automation.
I would contact Kepware for support.

MongoDB MapReduce weird bug

I'm trying this simple MapReduce operation:
function map() {
var gameDay = Math.floor((this.matchCreation - 1427846400000) / 86400000) + 1; // day of april 2015 when the game was played
this.teams.forEach (function (team){
**team.bans.forEach(function (ban){** // says bans is undefined
var value ={
banned : 1,
firstBanned: ( ((ban.pickTurn == 1) || (ban.pickTurn == 2))? 1 : 0 )
}
emit({championId: ban.championId,
day: Number(gameDay)}, value);
emit({championId: ban.championId,
day: "all"}, value);
});
});
}
function reduce(key, values) {
var a = values[0];
for(var i = 1 ; i<values.length ; i++){
var b = values[i]; // will merge 'b' into 'a'
a.banned += (b.banned? b.banned : 0);
a.firstBanned += (b.firstBanned? b.firstBanned : 0);
for (var attrname in b){
if(attrname != "banned" && attrname != "firstBanned")
a[attrname] = b[attrname];
}
}
return a;
}
matchesCollection.mapReduce(map, reduce, {
out: { reduce: "mapReduceResults" }
}, function (err, data){
if(err)
return callback (err);
callback (null, "OK");
});
It used to work before, but just when I tried to deploy the app after testing for a while, it seems to fail in this line: team.bans.forEach(function (ban){, says team.bans is undefined, although every one of the documents has a "teams" array and a "bans" array inside of each object in it, I even double checked it by querying the database and there is no document in which those fields dont exist.
So weird. The reduce function is a bit more complex but it seems to work alright, yet the map one (unlike Reduce, its supposed to be called just once per original document, right?) throws this unexplainable error. Could anyone give me some insight?
Sample input:
{
"_id": {
"$oid": "5531a63f2a3f135c11ed14a8"
},
"matchId": 1778704162,
"region": "NA",
"platformId": "NA1",
"matchMode": "CLASSIC",
"matchType": "MATCHED_GAME",
"matchCreation": 1427864425511,
"matchDuration": 1431,
"queueType": "URF_5x5",
"mapId": 11,
"season": "SEASON2015",
"matchVersion": "5.6.0.194",
"participants": [
{
"teamId": 100,
"spell1Id": 12,
"spell2Id": 4,
"championId": 81,
"highestAchievedSeasonTier": "SILVER",
"timeline": [],
"masteries": [],
"stats": {
"winner": false,
"champLevel": 19,
"item0": 1037,
"item1": 3078,
"item2": 3117,
"item3": 3035,
"item4": 3072,
"item5": 1038,
"item6": 3340,
"kills": 7,
"doubleKills": 1,
"tripleKills": 0,
"quadraKills": 0,
"pentaKills": 0,
"unrealKills": 0,
"largestKillingSpree": 3,
"deaths": 15,
"assists": 9,
"totalDamageDealt": 103191,
"totalDamageDealtToChampions": 22148,
"totalDamageTaken": 32924,
"largestCriticalStrike": 669,
"totalHeal": 2263,
"minionsKilled": 97,
"neutralMinionsKilled": 1,
"neutralMinionsKilledTeamJungle": 1,
"neutralMinionsKilledEnemyJungle": 0,
"goldEarned": 13923,
"goldSpent": 13273,
"combatPlayerScore": 0,
"objectivePlayerScore": 0,
"totalPlayerScore": 0,
"totalScoreRank": 0,
"magicDamageDealtToChampions": 6082,
"physicalDamageDealtToChampions": 15803,
"trueDamageDealtToChampions": 263,
"visionWardsBoughtInGame": 0,
"sightWardsBoughtInGame": 0,
"magicDamageDealt": 45997,
"physicalDamageDealt": 56651,
"trueDamageDealt": 543,
"magicDamageTaken": 25249,
"physicalDamageTaken": 7490,
"trueDamageTaken": 184,
"firstBloodKill": false,
"firstBloodAssist": false,
"firstTowerKill": false,
"firstTowerAssist": false,
"firstInhibitorKill": false,
"firstInhibitorAssist": false,
"inhibitorKills": 0,
"towerKills": 4,
"wardsPlaced": 2,
"wardsKilled": 0,
"largestMultiKill": 2,
"killingSprees": 1,
"totalUnitsHealed": 1,
"totalTimeCrowdControlDealt": 98
},
"participantId": 1,
"runes": []
},
... (9 more like that)
],
"participantIdentities": [],
"teams": [
{
"teamId": 100,
"winner": false,
"firstBlood": true,
"firstTower": false,
"firstInhibitor": true,
"firstBaron": false,
"firstDragon": true,
"towerKills": 6,
"inhibitorKills": 2,
"baronKills": 0,
"dragonKills": 3,
"vilemawKills": 0,
"dominionVictoryScore": 0,
"bans": [
{
"championId": 120,
"pickTurn": 1
},
{
"championId": 37,
"pickTurn": 3
},
{
"championId": 13,
"pickTurn": 5
}
]
},
{
"teamId": 200,
"winner": true,
"firstBlood": false,
"firstTower": true,
"firstInhibitor": false,
"firstBaron": false,
"firstDragon": false,
"towerKills": 11,
"inhibitorKills": 4,
"baronKills": 0,
"dragonKills": 0,
"vilemawKills": 0,
"dominionVictoryScore": 0,
"bans": [
{
"championId": 28,
"pickTurn": 2
},
{
"championId": 38,
"pickTurn": 4
},
{
"championId": 63,
"pickTurn": 6
}
]
}
]
}
Expected output:
{
_id: { championId: Number, day: Number }
value: { banned: Number, firstBanned: Number }
}
After that, its supposed to merge with the results of a previous MapReduce operation, copying all the fields of documents with the same key (in the reduce function), but thats irrelevant now since the error happens before...

Resources