Why mongodb stores some numbers as NumberLong? - mongodb

Mongodb is installed on Windows 8 and I use spring-data-mongodb to work with it.
I have collection with field pId, it's a number.
I see strange situation, mongodb stores some pId as simple number but some of them as NumberLong.
query:
db.mycollection.distinct("pId", {"dayDate" : { "$gte" : ISODate("2015-04-14T00:00:00.000Z")}})
output:
[ 61885, 61886, NumberLong(61887) ]
Why it happens and may I change something to use the same data type for all pId values?

I have been using Laravel with MongoDB, and as far as my understanding of MongoDB, I founded that:
If you're saving your data (numbers) in quote than, it will save as string, but if you assign number to variable in normal way (no quotes) then it will save in NumberLong format or when you are doing type cast by using (int)
Example.
$data = '1' (Stores as string)
$data = 1 or $data = (int)'1' (Store as NumberLong)

Related

Updating JSONB object using another table

I am trying to update a JSONB field in one table with data from another table. For example,
update ms
set data = data || '{"COMMERCIAL": 3.4, "PCT" : medi_percent}'
from mix
where mix.id = mss.data_id
and data_id = 6000
and set_id = 20
This is giving me the following error -
Invalid input syntax for type json
DETAIL: Token "medi_percent" is invalid.
When I change medi_percent to a number, I don't get this error.
{"COMMERCIAL": 3.4, "PCT" : medi_percent} is not a valid JSON text. Notice there is no string interpolation happening here. You might be looking for
json_build_object('COMMERCIAL', 3.4, 'PCT', medi_percent)
instead where medi_percent is now an expression (that will presumably refer to your mix column).

read values for a mongodb query from file

I'm trying to query all documents from a mongodb collection of which the criteria is inside a file.
criteria-file.txt:
value1
value2
value3
...
Currently I'm building the query like this
built-test.js.sh:
#!/bin/bash
echo 'db.collection.find({keyfield: {$in:[' > test.js
cat criteria-file.txt| while read i
do
echo "\"$i\"," >> test.js
done
echo ']}})' >> test.js
The query document is way under 16MB in size, but I wonder if there's a better way which is more elegant and efficient, especially, because over time I will most probably be over 16MB for the query document. I'm eager to get your suggestions.
BTW, I was wondering, for those 25K criteria values seeking in a collection with currently 200 million entries, the query time is only a bit over a minute and the CPU load doesn't seem to be too bad.
Thanks!
Read the file into an array using the cat() native shell method. Then, loop over the array of criteria values to find the matching documents and store all the documents in an array; this will be your list of matches.
var criteria_file = cat("criteria-file.txt");
var criteria_array = criteria_file.split("\n");
var result_ids_arr = [ ];
for (let value of criteria_array) {
let id_arr = db.collection.find( { keyfield: value }, { _id: 1} ).toArray();
result_ids_arr = result_ids_arr.concat(id_arr);
}
The result array of the _id values, e.g.: [ { "_id" : 11 }, { "_id" : 34 }, ... ]
All this JavaScript can be run from the command prompt or the mongo shell, using the load().
Split the criteria file into different chunks ensuring that the chunks don't exceed 16MB.
Run the same query on each chunk only now you can run the queries in parallel.
if you want to get extra fancy you can use the aggregation pipeline to do a $match query and send all the output results from each query to a single results collection using $mergeenter link description here.

Does Mongodb queries a record by DateTime quicker than by String?

For example, this is a record:
{
"_id" : ObjectId("576bc7a48114a14b47920d60"),
"id" : "TEST0001",
"testTime" : ISODate("2016-06-23T11:28:06.529+0000")
}
The testTime is ISODate, does Mongodb query the record by testTime is quicker than this? :
{
"_id" : ObjectId("576bc7a48114a14b47920d60"),
"id" : "TEST0001",
"testTime" : "2016-06-23 11:28:06"
}
yes it does.
The difference is produced on basis that date object is stored as a number in dateTime object.
To understood this we could go with this ilustration:
When there is a query on dateTime filed and dateTime is stored in numerical object, that means we have comparison on numbers. Mongo will compare object with size of 64 bits (8bytes) see here with same object.
When comparing string, mongo loads string like this: 2016-06-27T08:39:44.000 which is 23 chars*2bytes (utf) => 46 bytes to compare in memory and need to check all bytes from highest to lowest one..
Now, you know the answer why it is faster using dateObject instead of string.
Any comments welcome!
link here
Comparison/Sort Order
MinKey (internal type)
Null
Numbers (ints, longs, doubles)
Symbol, String
Object
Array
BinData
ObjectId
Boolean
Date
Timestamp
Regular
Expression
MaxKey (internal type)

How to format a number 123456 to 123,456 in mongodb

I am getting a number (e.g., 450000) as a result from a mongodb query. I want to format the number with a thousands separator (like currency) as 450,000.
Number: 1593324
Expected Output: 1,593,324
How can I achieve this in mongodb?
you can't achieve this in mongodb because this is not programming language.
But You can use:
variableName.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
and then call to store this string in database
example:
var test = 1593324;
test.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
and then output i m getting :
1,593,324

Getting a MongoDB document's field value into a variable

I am using mongo's shell and want to do what is basically equivalent to "SQL's select col INTO var" and then use the value of var to look up other rows in the same table or others (Joins). For example, in PL/SQL I will declare a variable called V_Dno. I also have a table called Emp(EID, Name, Sal, Dno). I can access the value of Dno for employee 100 as, "Select Dno into V_Dno from Emp where EID = 100). In MongoDB, when I find the needed employee (using its _id), I end up with a document and not a value (a field). In a sense, I get equivalent to the entire row in SQL and not just a column. I am doing the following to find the given emp:
VAR V_Dno = db.emp.find ({Eid : 100}, {Dno : 1});
The reason I want to do this to traverse from one document into the other using the value of a field. I know I can do it using the DBRef, but I wanted to see if I could tie documents together using this method.
Can someone please shed some light on this?
Thanks.
find returns a cursor that lets you iterate over the matching documents. In this case you'd want to use findOne instead as it directly returns the first matching doc, and then use dot notation to access the single field.
var V_Dno = db.emp.findOne({Eid : 100}, {Dno : 1}).Dno;
Using your query as a starting point:
var vdno = db.emp.findOne({Eid: 100, Dno :1})
This returns a document from the emp collection where the Eid = 100 and the Dno = 1. Now that I have this document in the vdno variable I can "join" it to another collection. Lets say you have a Department collection, a document in the department collection has a manual reference to the _id field in the emp collection. You can use the following to filter results from the department collection based on the value in your variable.
db.department.find({"employee._id":vdno._id})