I am very new to Mongo so I am most likely missing something very obvious, but I have not found anything on the internet to tell me what it is. I am trying to run a mongodb query from a JavaScript file but I am having trouble.
Mongo seems to be ignoring the projection part of the query, everything else is coming through fine though.
criteria = ' { "powersave_enabled" : false, "tx_rate" : { $lt : 26000 }, "rx_rate" : { $lt : 26000 }, "btyes-r" : { $ne: 0 } } ';
projection = ' {"_id":0, "hostname" : 1, "rssi" : 1, "mac" : 1, "ap_mac" : 1, "noise" : 1} ';
command = criteria + ', ' + projection;
accessPoints = db.cache_sta.find(command);
while (accessPoints.hasNext()){
printjson( accessPoints.next() );
}
I have printed out the command and tried running it myself in mongo and it seems to be working right, but something in the JS is messed up.
Thanks in advance!
Instead of concatenate the criteria and the projection pass them as objects like this:
criteria = { "powersave_enabled" : false, "tx_rate" : { $lt : 26000 }, "rx_rate" : { $lt : 26000 }, "btyes-r" : { $ne: 0 } };
projection = {"_id":0, "hostname" : 1, "rssi" : 1, "mac" : 1, "ap_mac" : 1, "noise" : 1};
accessPoints = db.cache_sta.find(criteria, projection);
while (accessPoints.hasNext()){
printjson( accessPoints.next() );
}
Related
I am making query for my orders list, here is the data structure and my database rules:
I use a query like this to find out whether the latest price hit the tp or sl price like this:
function GetBuyList(symbol, currentPrice) {
//Less than or equal to, for buying search tp lesser than current price
var buy_tp = db.ref(`orders/active_orders/${symbol}`).orderByChild("tp").startAt(`buy_tp_${0}`).endAt(`buy_tp_${currentPrice}`)
//More than or equal to, for buying search sl higher than current price
var buy_sl = db.ref(`orders/active_orders/${symbol}`).orderByChild("sl").startAt(`buy_sl_${currentPrice}`).endAt(`buy_sl_${100000000}`)
buy_tp.once("value", function (snapshot) {
// do some stuff once
if (snapshot.val() !== null) {
ProcessOrders(snapshot.val(), 'tpHit', currentPrice)
}
});
buy_sl.once("value", function (snapshot) {
// do some stuff once
if (snapshot.val() !== null) {
ProcessOrders(snapshot.val(), 'slHit', currentPrice)
}
});
}
For price that is in lower value like 1.211, it working fine, but when the price goes larger, the buy_sl query is not working, but the buy_tp query is still working fine. Example, when I query for the price like 34886 for the data below the buy_sl is not working:
Edit:
Hi Frank, herein the json exported:
{
"active_orders" : {
"BTCUSD" : {
"-Masii03kq9LvuLfWOyG" : {
"close_type" : "None",
"lot_size" : 1,
"order_price" : 34888.17,
"sl" : "buy_sl_34887",
"symbol" : "BTCUSD",
"tp" : "buy_tp_34889",
"ts" : 1622301925456,
"type" : "buy",
"uid" : "6XaKYgXCsuMNg1d5bWYHg6ej5sd2"
}
},
"EURUSD" : {
"-MasVPCtD4sdPCcdF9S9" : {
"close_type" : "None",
"lot_size" : 1,
"order_price" : 1.211,
"sl" : "buy_sl_1.210",
"symbol" : "EURUSD",
"tp" : "buy_tp_1.23",
"ts" : 1622298174339,
"type" : "buy",
"uid" : "6XaKYgXCsuMNg1d5bWYHg6ej5sd2"
}
},
"USDJPY" : {
"-MasWoRREHQhvOR6iQ8G" : {
"close_type" : "None",
"lot_size" : 1,
"order_price" : 109.861,
"sl" : "buy_sl_107.0",
"symbol" : "USDJPY",
"tp" : "buy_tp_110",
"ts" : 1622298543910,
"type" : "buy",
"uid" : "6XaKYgXCsuMNg1d5bWYHg6ej5sd2"
}
}
}
}
Example, when I perform the function GetBuyList("EURUSD", 1.3) or GetBuyList("EURUSD", 1.1), the result returned as:
{
'-MasVPCtD4sdPCcdF9S9': {
close_type: 'None',
lot_size: 1,
order_price: 1.211,
sl: 'buy_sl_1.210',
symbol: 'EURUSD',
tp: 'buy_tp_1.23',
ts: 1622298174339,
type: 'buy',
uid: '6XaKYgXCsuMNg1d5bWYHg6ej5sd2'
}
}
When I perform the function like this, GetBuyList("BTCUSD", 34890), it would return:
{
'-Masii03kq9LvuLfWOyG': {
close_type: 'None',
lot_size: 1,
order_price: 34888.17,
sl: 'buy_sl_34887',
symbol: 'BTCUSD',
tp: 'buy_tp_34889',
ts: 1622301925456,
type: 'buy',
uid: '6XaKYgXCsuMNg1d5bWYHg6ej5sd2'
}
}
But when I run this, GetBuyList("BTCUSD", 34886), nothing is return.
sl and tp are both strings and because they are, they won't be parsed as numbers and instead are subject to lexiographic sorting.
One of the most common examples of this happening is if you look at a file list in a folder:
0.jpg
1.jpg
10.jpg
11.jpg
12.jpg
2.jpg
3.jpg
4.jpg
5.jpg
6.jpg
7.jpg
8.jpg
9.jpg
If you can't switch from using strings, you need to pad the number with your expected maximum number:
000.jpg
001.jpg
002.jpg
003.jpg
004.jpg
005.jpg
006.jpg
007.jpg
008.jpg
009.jpg
010.jpg
011.jpg
012.jpg
const formatWithPadding = (inp, digits) => {
let n = Number(inp), nStr = `${Math.abs(n)}`, sign = n<0;
return (sign ? '+' : '-') + (
nStr.length > digits
? nStr
: `${"0".repeat((digits || 1) - 1)}${nStr}`.slice(-digits)
)
};
const tpVal = 1.210;
const [integerPart, fractionalPart] = String(tpVal).split(".");
const tp = `buy_tp_${formatWithPadding(integerPart, 6)}.${fractionalPart || 0}`;
// tp is "buy_tp_+000001.210"
I have a json object that looks like this and I have read this into a variable called myData
{
{
issue : 'A1',
pdate : '2021-05-21'
type : 'small'
},
{
issue : 'A2',
pdate : '2021-05-21'
type : 'med'
},
{
issue : 'A4',
pdate : '2021-05-21'
type : 'large'
},
{
issue : 'A22',
pdate : '2021-06-21'
type : 'small'
},
{
issue : 'A222',
pdate : '2021-06-21'
type : 'small'
},
{
issue : 'A422',
pdate : '2021-06-21'
type : 'small'
}
}
I want to get how many items of each time exist on a given day.
My current code is something like this
var dict = {};
myData.map((elem) => {
var xkey = elem.pdate;
dict[xkey] = xkey in dict ? dict[xkey] + 1 : 1;
});
this given me a dict like this
2021-05-21 : 3,
2021-06-21 : 2
Now I want to convert this into a dictionary or a 2D array so I can know how many diff type of items are present on a given day.
{
'2021-05-21' : {'small':1,'med':1,'large':1},
'2021-06-21' : {'small' : 2}
}
Please can someone help me write this. I have tried diff combinations of if conditions to make this work but I am unable to get this. Also this doesn't have to be a dictionary, either an array or a dict, as long as I am able to iterate over it later.
Hope this works:
const test = [{
issue : 'A1',
pdate : '2021-05-21',
type : 'small'
},
{
issue : 'A2',
pdate : '2021-05-21',
type : 'med'
},
{
issue : 'A4',
pdate : '2021-05-21',
type : 'large'
},
{
issue : 'A22',
pdate : '2021-06-21',
type : 'small'
},
{
issue : 'A222',
pdate : '2021-06-21',
type : 'small'
},
{
issue : 'A422',
pdate : '2021-06-21',
type : 'small'
}]
const output = {};
test.forEach((obj) => {
if (!output[obj.pdate]) {
output[obj.pdate] = {};
}
if (!output[obj.pdate][obj.type]) {
output[obj.pdate][obj.type] = 0;
}
output[obj.pdate][obj.type] += 1;
});
console.log(output);
I would like that MongoDB clears data from its collections after %seconds pass. I am setting index, but collection doesn't gets cleared after a while, all the documents are still present.
What am I doing wrong?
DB Version: 3.2
Setting Index:
db.collection('history').ensureIndex(
{ '_id': 1, 'created': 1 },
{ unique: true, background: true, w: 1, expireAfterSeconds: 60}
);
// or
db.collection('history').createIndex(
{ '_id': 1, 'created': 1 },
{ unique: true, background: true, w: 1, expireAfterSeconds: 60}
);
// history document
var _history = {
_id: new ObjectId(),
created: new Date()
};
Collection history, index:
var historyCollectionIndex = [
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "guardian_dev.history"
},
{
"v" : 1,
"unique" : true,
"key" : {
"_id" : 1,
"created" : 1
},
"name" : "_id_1_created_1",
"ns" : "guardian_dev.history",
"background" : true,
"expireAfterSeconds" : 60
}
]
Additional question that is connected to creating indexes.
Now, it can happen that two entries have the same created value, and because of this, mongo is now throwing an error of E11000 duplicate key error collection.
Is it possible to add created and expireAfterSeconds, but created doesn't have to be uniq?
According to the MongoDB site:
The TTL index is a single field index. Compound indexes do not support the TTL property.
If you remove the _id: 1 index and instead just use created then it should behave as you expect
According to the documentation, the TTL index is a single field index. Compound indexes do not support the TTL property. You should create the index as follows:
db.collection('history').ensureIndex(
{'created': 1 },
{ unique: true, background: true, w: 1, expireAfterSeconds: 60}
);
I have tested it and this index, unlike the one in your question, clears out the records correctly.
I have this schema with mongoose
schema = new Schema({
id: {
type: String,
},
embedded: [embeddedSchema]
});
embeddedSchema = new Schema({
value: {
type: String,
},
});
This can produce something like :
{
"_id" : ObjectId("5454f4f1073cc3b529320f79"),
"embedded" : [
{
"value" : 123,
} , {
"value" : 123,
},
{
"value" : 123423,
}
]
}
/* 1 */
{
"_id" : ObjectId("5454f508910ef3b82970f11d"),
"embedded" : [
{
"value" : 1,
} , {
"value" : 2,
},
{
"value" : 9999999,
}]
}
I would like to sort the schema collection by the biggest value of embedded doc.
Which query can produce this kind of result ?
Thanks you!
When you sort descending on an array element field like value, MongoDB uses the maximum value of that field among all elements in the array.
So in this case it would be:
MyModel.find().sort('-embedded.value').exec(callback);
I'm trying to increment a field in my mongodb document using the $inc operator. The field I am trying to increment is a sub-property of my document's count field, e.g.:
mydoc: {
count: {
schedules: 0
}
}
When I try this:
> db.mydocs.update({ _id: new ObjectId('4db5c2f3dc73c5afdaffd636') }, { $inc: { count.schedules: 1 } }, { upsert: true, safe: true }, null);
from my mongo shell, I get this error message:
Mon Apr 25 11:59:05 SyntaxError: missing : after property id (shell):1
I've tried several syntax variations with similar results. Do I need to take a different approach to this? I've verified my document exists and has a count.schedules field that is set to 0.
I can directly set the value using a command like this:
db.mydocs.update({ _id: new ObjectId('4db5c2f3dc73c5afdaffd636') }, { $set: { count: { schedules:1 } } }, null, null);
But if I try that syntax for the $inc operation, I get this error:
Modifier $inc allowed for numbers only
Thanks
Yes, you can do a $inc only on numbers. Here is how I tried to reproduce your problem, you can notice I've used proper quotes, which is the reason you are seeing the missing : after property id(shell):1 error.
> db.schedules.save({"mydoc": { "count": { "schedules": 0}}});
> db.schedules.find();
{ "_id" : ObjectId("4db5cf199e631c2a52a7c643"), "mydoc" : { "count" : { "schedules" : 0 } } }
> db.schedules.update({ _id: new ObjectId("4db5cf199e631c2a52a7c643") }, { $inc: { "mydoc.count.schedules": 1 } }, { upsert: true, safe: true }, null);
> db.schedules.find();
{ "_id" : ObjectId("4db5cf199e631c2a52a7c643"), "mydoc" : { "count" : { "schedules" : 1 } } }
Hope this helps!
I think this may be a simple fix. Try putting quotes around count.schedules like so:
db.mydocs.update({ _id: new ObjectId('4db5c2f3dc73c5afdaffd636') }, { $inc: { 'count.schedules': 1 } }, { upsert: true, safe: true }, null);