Mongo greater than comparison returns 0 - mongodb

I am trying to count all car dealers who's total fleet units is over 1000. This is the code I wrote to do it, however, it returns 0 and I know for a fact there are quite a few records in this data set that are over 1000.
db.Car_Dealership.find({Totalfleetunits : {$gte: 1000} }).count()
This is a sample of what's in my database, both records have total fleets over 1000. Any ideas why it returns 0?
"_id" : ObjectId("5a203ab0b9574375830354d4"),
"2016rank" : 6,
"Dealershipgroupname" : "Hendrick Automotive Group",
"Address" : "6000 Monroe Road",
"City/State/Zip" : "Charlotte, NC 28212",
"Phone" : "(704) 568-5550",
"Companywebsite" : "www.hendrickauto.com",
"Topexecutive" : "Rick Hendrick",
"Topexecutivetitle" : "chairman",
"Totalnewretailunits" : "117,946",
"Totalusedunits" : "88,458",
"Totalfleetunits" : "4,646",
"Totalwholesaleunits" : "56,569",
"Total_units" : "267,619",
"Total_number_of _dealerships" : 103,
"Grouprevenuealldepartments*" : "$8,551,253,132",
"2015rank" : 6
}
{
"_id" : ObjectId("5a203ab0b9574375830354d5"),
"2016rank" : 5,
"Dealershipgroupname" : "Sonic Automotive Inc.?",
"Address" : "4401 Colwick Road",
"City/State/Zip" : "Charlotte, NC 28211",
"Phone" : "(704) 566-2400",
"Companywebsite" : "www.sonicautomotive.com",
"Topexecutive" : "B. Scott Smith",
"Topexecutivetitle" : "CEO",
"Totalnewretailunits" : "134,288",
"Totalusedunits" : "119,174",
"Totalfleetunits" : "1,715",
"Totalwholesaleunits" : "35,098",
"Total_units" : "290,275",
"Total_number_of _dealerships" : 112,
"Grouprevenuealldepartments*" : "$9,731,778,000",
"2015rank" : 4

That happens because the value of Totalfleetunits is stringType.
Now to solve your problem you have to options.
option 1:
You can change your schema for Totalfleetunits to the type of Number and change all the documents Totalfleetvalues value from string to a number. Like,
"Totalfleetunits": "4,646" needs to be changed with "Totalfleetunits"
: "4646"
option 2:
You can use javascript in your query to first remove , from your value then check the Totalfleetunits value for greater than or equal to ( >= ). Only need to change a single line of code as I given below.
db.Car_Dealership.find("this.Totalfleetunits.replace(',','') >= 1000").count()

Related

In Mongodb, after create the text index, when query using text filter there is no any output showing

In Mongodb, I have created the collection as follows.
db.test.insertMany([
{CustomerKey : "11026", FirstName : "Harold", LastName : "Sai", BirthDate : new Date("1951-10-1"),MaritalStatus : "S", Gender : "M", EmailAddress : "harold3#adventure-works.com", YearlyIncome : 30000, TotalChildren : 2, NumberChildrenAtHome : 0, EnglishEducation : "Partial College", EnglishOccupation : "Clerical", NumberCarsOwned : 2, AddressLine1 : {House_No : 2596, Area_Name: "Franklin Canyon Road"}, Phone : "1 (11) 500 555-0131", DateFirstPurchase : new Date("2011-10-1"), CommuteDistance : "1-2 Miles"} ,
{CustomerKey : "11027", FirstName : "Jessie", LastName : "Zhao", BirthDate : new Date("1952-6-5"),MaritalStatus : "M", Gender : "M", EmailAddress : "jessie16#adventure-works.com", YearlyIncome : 30000, TotalChildren : 2, NumberChildrenAtHome : 0, EnglishEducation : "Partial College", EnglishOccupation : "Clerical", NumberCarsOwned : 2, AddressLine1 : {House_No : 8211, Area_Name: "Leeds Ct."}, Phone : "1 (11) 500 555-0184", DateFirstPurchase : new Date("2011-6-1"), CommuteDistance : "5-10 Miles"} ,
{CustomerKey : "11028", FirstName : "Jill", LastName : "Jimenez", BirthDate : new Date("1951-10-9"),MaritalStatus : "M", Gender : "F", EmailAddress : "jill13#adventure-works.com", YearlyIncome : 30000, TotalChildren : 2, NumberChildrenAtHome : 0, EnglishEducation : "Partial College", EnglishOccupation : "Clerical", NumberCarsOwned : 2, AddressLine1 : {House_No : 213, Area_Name: "Valencia Place"}, Phone : "1 (11) 500 555-0116", DateFirstPurchase : new Date("2011-10-1"), CommuteDistance : "1-2 Miles"} ,
]);
Following is the output of query :(emailaddress with Harold Available)
I have set "EmailAddress" field as Text Index.
db.test.createIndex({EmailAddress : "text"})
But When i Query using the following code, there is no any output for text filter.
db.test.find({$text:{$search:"harold"}})
What you are looking for is
db.test.find({"EmailAddress":{"$regex":"harold"}})
As you are looking for some sort of pattern match.
A text index stores the field in a tokenised form by removing stop words, replacing words by their stem words etc
You can read more about it here https://docs.mongodb.com/manual/text-search/#-text-operator
regex operator and its index use: https://docs.mongodb.com/manual/reference/operator/query/regex/
Text indexes do not support partial word matches. They are expected to find the whole word in a sentence. In your example harold is considered as part of the word harold3#adventure-works.com thus you are trying to perform a partial word match. Consider the following document as a test case...
db.test.insert({
"CustomerKey" : "11026",
"FirstName" : "Harold",
"LastName" : "Sai",
"BirthDate" : ISODate("1951-10-01T00:00:00Z"),
"MaritalStatus" : "S",
"Gender" : "M",
"EmailAddress" : "harold is at harold3#adventure-works.com",
"YearlyIncome" : 30000,
"TotalChildren" : 2,
"NumberChildrenAtHome" : 0,
"EnglishEducation" : "Partial College",
"EnglishOccupation" : "Clerical",
"NumberCarsOwned" : 2,
"AddressLine1" : {
"House_No" : 2596,
"Area_Name" : "Franklin Canyon Road"
},
"Phone" : "1 (11) 500 555-0131",
"DateFirstPurchase" : ISODate("2011-10-01T00:00:00Z"),
"CommuteDistance" : "1-2 Miles"
})
... now, your original query will find it because the whole word harold is found in the field EmailAddress.
While Text indexes do no support partial word matches they will allow word-stemming. For example if you search on run, it will find running.
Another option is to use MongoDB Atlas. Atlas supports Apache Lucene based search indexes which provide partial and fuzzy match capabilities.
For another reference to a similar SO article see MongoDB Full and Partial Text Search.

mongodb lookup giving empty array

BED_MAST this is my one collection bed_mast contains WARD_ID and want to perform join to my other collection with is WARD_MAST given below.
{
"_id" : ObjectId("5e53c95a26b0e5ad0fb46376"),
"Bed_id" : "bd-10",
"WARD_ID" : "4",
"OCCUPIED" : "0",
"BED_TYPE" : "single AC"
}
{
"_id" : ObjectId("5e53c95a26b0e5ad0fb46377"),
"Bed_id" : "bd-11",
"WARD_ID" : "1",
"OCCUPIED" : "0",
"BED_TYPE" : "single Non AC"
}
WARD_MAST this is my WARD_MAST having ward_id. but while I am putting lookup I am not getting any data.
{
"_id" : ObjectId("5e53c95b26b0e5ad0fb46544"),
"patient_id" : null,
"ward_id" : 1,
"total_beds" : 55,
"ward_name" : "Ward 1"
}
{
"_id" : ObjectId("5e53c95d26b0e5ad0fb46545"),
"patient_id" : null,
"ward_id" : 2,
"total_beds" : 63,
"ward_name" : "Ward 2"
}
MY query is
db.BED_MAST.aggregate([{$lookup:{'from':"WARD_MAST",'localField':"WARD_ID",'foreignField':"ward_id",'as':"lookup_value"}}]).pretty()
output: I have confirmed the data by running this query to MySQL there it is working fine
{
"_id" : ObjectId("5e53c95b26b0e5ad0fb46388"),
"Bed_id" : "bd-28",
"WARD_ID" : "6",
"OCCUPIED" : "0",
"BED_TYPE" : "NICU",
"lookup_value" : [ ]
}
SAMPLE VALUES DATA IS GIVEN ALL DATA IS NOT POSSIBLE TO GIVE. I know it was asked 1000 times but not able to resolve this question. tried to solve with lookup. but it showing blank space. Is anything I am missing.
The problem is BED_MAST collection's WARD_ID has string values and WARD_MAST collection's ward_id has Number values.

how to calculate time difference based on 2 fields in mongodb

I am familiar to simple mongodb queries but this one is a bit complex for me. Here, what I am trying to achieve is on the basis of jsonObject.callID and jsonObject.mobile fields I have to calculate time difference of jsonObject.timestamp. For example in below sample documents, jsonObject.callID and mobile will remain same for jsonObject.action start and end. So based on jsonObject.callID and jsonObject.mobile, I have to subtract the jsonObject.timestamp. jsonObject.callId will be same for two interval actions i.e. start and end with their same jsonObject.mobile numbers.
{
"_id" : ObjectId("5df9bc5ee5e7251030535df5"),
"_class" : "com.abc.mongo.docs.IvrMongoLog",
"jsonObject" : {
"mode" : "ivr",
"callID" : "33333",
"callee" : "128",
"action" : "end",
"mobile" : "218924535466",
"timestamp" : "2019-12-18 16:18:12"
}
}
{
"_id" : ObjectId("5df9bc3de5e7251030535df4"),
"_class" : "com.abc.mongo.docs.IvrMongoLog",
"jsonObject" : {
"mode" : "ivr",
"callID" : "33333",
"callee" : "128",
"action" : "start",
"mobile" : "218924535466",
"timestamp" : "2019-12-18 16:12:11"
}
}
So I am trying to achieve a output like below:
{
"callee" : "128",
"mobile" : "218924535466",
"callID" : "33333",
"minutes_of_call" : "6" // difference of "2019-12-18 16:18:12" - "2019-12-18 16:12:11"
}
subsequently I need such results for next documents...
Kindly assist.

How to find something from an array in mongo

{
"_id" : ObjectId("586aac4c8231ee0b98458045"),
"store_code" : NumberInt(10800),
"counter_name" : "R.N.Electric",
"address" : "314 khatipura road",
"locality" : "Khatipura Road (Jhotwara)",
"pincode" : NumberInt(302012),
"town" : "JAIPUR",
"gtm_city" : "JAIPUR",
"sales_office" : "URAJ",
"owner_name" : "Rajeev",
"owner_mobile" : "9828024073",
"division_mapping" : [//this contains only 1 element in every doc
{
"dvcode" : "cfc",
"dc" : "trade",
"beatcode" : "govindpura",
"fos" : {
"_id" : ObjectId("586ab8318231ee0b98458843"),
"loginid" : "9928483483",
"name" : "Arpit Gupta",
"division" : [
"cfc",
"iron"
],
"sales_office" : "URAJ", //office
"gtm_city" : "JAIPUR" //city
},
"beat" : {
"_id" : ObjectId("586d372b39f64316b9c3cbd7"),
"division" : {
"_id" : ObjectId("5869f8b639f6430fe4edee2a"),
"clientdvcode" : NumberInt(40),
"code" : "cfc",
"name" : "Cooking & Fabric Care",
"project_code" : "usha-fos",
"client_code" : "usha",
"agent_code" : "v5global"
},
"beatcode" : "govindpura",
"sales_office" : "URAJ",
"gtm_city" : "JAIPUR",
"active" : true,
"agency_code" : "v5global",
"client_code" : "USHA_FOS",
"proj_code" : "usha-fos",
"fos" : {
"_id" : ObjectId("586ab8318231ee0b98458843"),
"loginid" : "9928483483",
"name" : "Arpit Gupta",
"division" : [
"cfc",
"iron"
],
"sales_office" : "URAJ",
"gtm_city" : "JAIPUR"
}
}
}
],
"distributor_mail" : "sunil.todi#yahoo.in",
"project_code" : "usha-fos",
"client_code" : "usha",
"agent_code" : "v5global",
"distributor_name" : "Sundeep Electrical"
}
I am having only 1 element in division_mapping's array and I want to find those documents whose dc in division_mapping is trade.
I have tried following:
"division_mapping":{$elemMatch:{$eq:{"dc":"trade"}}}})
Dont know what I am doing wrong.
//Maybe I have to unwind the array but is there any other way?
According to MongoDB documentation
The $elemMatch operator matches documents that contain an array
field with at least one element that matches all the specified query
criteria.
According to above mentioned description to retrieve only documents whose dc in division_mapping is trade please try executing below mentioned query
db.collection.find({division_mapping:{$elemMatch:{dc:'trade'}}})

MongoDB: How to find nth highest salary from collection

I need to find the nth highest salary in a mongodb from Employees collection.
also would be really helpful if someone could gimme an idea of applying joins in mongodb.
This should work
db.Employees.find({}).sort({"Emp salary":-1}).limit(1) //for first highest salary
db.Employees.find({}).sort({"Emp salary":-1}).skip(1).limit(1) // for second highest salary
Similarly you can do db.Employees.find({}).sort({"Emp salary":-1}).skip(nthVarible - 1).limit(1).
Try this out:
db.salary.find({}).sort({s:-1}).skip(1).limit(1);
For your second requirement - MongoDB is noSQL DB, not a transnational DB. It does not support joins.
I found a two-step process to do it. it will work in the scenario if there are multiple records with salary same as highest.
Records I have
{ "_id" : ObjectId("5cc04b02536dc2e493697b4e"), "name" : "Ankit" }
{ "_id" : ObjectId("5cc0504a536dc2e493697b50"), "name" : "Ankit", "salary" : 1000, "email" : "a#b.com", "joining_date" : ISODate("2019-04-24T12:02:18.528Z") }
{ "_id" : ObjectId("5cc0504a536dc2e493697b51"), "name" : "Priya", "salary" : 1300, "email" : "p#b.com", "joining_date" : ISODate("2019-04-24T12:02:18.528Z") }
{ "_id" : ObjectId("5cc0504a536dc2e493697b52"), "name" : "Raj", "salary" : 1200, "email" : "rj#b.com", "joining_date" : ISODate("2019-04-24T12:02:18.528Z") }
{ "_id" : ObjectId("5cc0504a536dc2e493697b53"), "name" : "Vishu", "salary" : 1500, "email" : "v#b.com", "joining_date" : ISODate("2019-04-24T12:02:18.528Z") }
{ "_id" : ObjectId("5cc0504a536dc2e493697b54"), "name" : "Rahul", "salary" : 2000, "email" : "ra#b.com", "joining_date" : ISODate("2019-04-24T12:02:18.528Z") }
{ "_id" : ObjectId("5cc08b5d536dc2e493697b57"), "name" : "Tushar", "salary" : 2000, "email" : "tu#b.com", "joining_date" : ISODate("2019-04-24T16:14:21.061Z") }
Find distinct salaries and store in a variable
sal = db.employee.distinct("salary").sort()
Output: [ 1000, 1200, 1300, 1500, 2000 ]
You can get the second highest salary from this array itself. Below query will give you the record with that salary
db.employee.find({salary:{$lt:sal[sal.length-1]}}).sort({"salary":-1}).limit(1)
Output:
{ "_id" : ObjectId("5cc0504a536dc2e493697b53"), "name" : "Vishu", "salary" : 1500, "email" : "v#b.com", "joining_date" : ISODate("2019-04-24T12:02:18.528Z") }
I see this question has been asked in many technical interviews.
OBJ = client.my_db.employee_table
OBJ.find({}).sort('salary', -1).limit(1)
1 in the index 1 implies ascending order
-1 in the index 1 implies descending order.
As we wanna find the highest salary from the table, we must mention -1.
To find the nth highest salary in the table.
OBJ.find({}).sort('salary',-1).skip(n-1).limit(1)
To eliminate rows, we use OFFSET in Mysql/SQL Likewise we must use skip() in MongoDB
For first, second maximum salary if having multiple records in Mongodb:
METHOD I : (If NO multiple records exists)
db.details.find({}).sort({"salary":-1}).limit(1) ==> First Highest Salary
db.details.find({}).sort({"salary":-1}).skip(1).limit(1) ==> Second Highest Salary
METHOD II : (If MULTIPLES records exists)
Second Maximum Salary :
sal = db.details.distinct("salary").sort() ==> sal = [1000, 1400, 1500, 1700, 2000]
db.details.find({salary:{$lt:sal[sal.length-1]}}).sort({"salary":-1}).limit(1)
db.sales.aggregate({$group:{_id:'$salary'}},{$sort:{salary:-1}},{$skip: 1},{$limit:1})
In $skip value you can use n number to skip n number of rows.