MongoDB GeoNear Aggregate - mongodb

The question is:
Consider the following location: [-72, 42] and the range (circle) of radius 2 around this point. Write a query to find all the states that intersect this range (circle). Then, you should return the total population and the number of cities for each of these states. Rank the states based on number of cities.
I have written this so far:
db.zips.find({loc: {$near: [-72, 42], $maxDistance: 2}})
and a sample output of that is:
{ "city" : "WOODSTOCK", "loc" : [ -72.004027, 41.960218 ], "pop" : 5698, "state" : "CT", "_id" : "06281" }
In SQL i would simply do a group by "state", how would i be able to do that here while also counting all the cities and total population?

assuming you follow the mongoimport routine for its zipcode data (i brought mine into a collection called zips7):
mongoimport --db mydb --collection zips7 --type json --file c:\users\drew\downloads\zips.json
or
mongoimport --db mydb --collection zips7 --type json --file /data/playdata/zips.json
(depending on your OS and paths)
then
db.zips7.ensureIndex({loc:"2d"})
db.zips7.find({loc: {$near: [-72, 42], $maxDistance: 2}}).forEach(function(doc){
db.zips8.insert(doc);
});
note that db.zips7.stats() shows like 30k rows and zips8 has 100 rows
db.zips8.aggregate( { $group :
{ _id : "$state",
totalPop : { $sum : "$pop" },
town_count:{$sum:1}
}}
)
{
"result" : [
{
"_id" : "RI",
"totalPop" : 39102,
"town_count" : 10
},
{
"_id" : "MA",
"totalPop" : 469583,
"town_count" : 56
},
{
"_id" : "CT",
"totalPop" : 182617,
"town_count" : 34
}
],
"ok" : 1
}

Syntax in mongoid
Zips.where(:loc => {"$within" => {"$centerSphere"=> [[lng.to_f,lat.to_f],miles.to_f/3959]}})
Example:
Zips.where(:loc => {"$within" => {"$centerSphere"=> [[-122.4198185,37.7750454],2.0/3959]}})

Related

Export Mongodb subdocuments to CSV

I am having problems exporting subdocuments that are stored in MongoDB to a .CSV.
My data: a mongo collection that contains a unique user ID and scores from personality quizzes.
I would like a CSV that has three columns: user_id, name, raw_score. To add a further layer of complexity, within the 'scales' subdocument some users will have more than two entries (some quizzes produced more than 2 personality scores).
An example of my data minus documents that I am not interested in:
"assessment":{
"user_id" : "5839b1a654842f35617ad100",
"submissions" : {
"results" : {
"scales" : [
{
"scale" : {
"name" : "Security",
"code" : "SEC",
"multiplier" : 1
},
"raw_score" : 2
},
{
"scale" : {
"name" : "Power",
"code" : "POW",
"multiplier" : -1
},
"raw_score" : 3
}
],
}
}
}
}
I have tried using mongoexport but this produces a CSV that only has a user_id column.
rekuss$ mongoexport -d production_hoganx_app -c assessments --type=csv -o app_personality.csv -f user_id,results.scales.scale.name,results.scales.raw_score
Any ideas where I am going wrong?
Please let me know if you need anymore information.
Many thanks
You should try removing '=' sign from type. You could try --type csv

How to export the fields of an embedded document in mongodb

My doc:
db.org.insert({
"id" : 28,
"organisation" : "Mickey Mouse company",
"country" : "US",
"contactpersons" : [{
"title" : "",
"typecontact" : "D",
"mobilenumber" : "757784854",
"firstname" : "Mickey",
"lastname" : "Mouse",
"emailaddress" : "mickey#mouse.com"
},
{
"title" : "",
"typecontact" : "E",
"mobilenumber" : "757784854",
"firstname" : "Donald",
"lastname" : "Duck",
"emailaddress" : "donald#duck.com"
}],
"modifieddate" : "2013-11-21T16:04:49+0100"
});
My query:
mongoexport --host localhost --db sample --collection org --type csv --fields country,contactpersons.0.firstname,contactpersons.0.emailaddress --out D:\info_docs\org.csv
By this query, I'm able to get only the first document values of the contactpersons.But, I'm trying to export the second document values also.
How can I resolve this issue ? Can anyone please help me out regarding this ...
You're getting exactly the first document in contactpersons because you are only exporting the first element of the array (contactpersons.0.firstname). mongoexport can't export several or all elements of an array, so what you need to do is to unwind the array and save it in another collection. You can do this with the aggregation framework.
First, do an $unwind of contactpersons, then $project the fields you want to use (in your example, country and contactpersons), and finally save the output in a new collection with $out.
db.org.aggregate([
{$unwind: '$contactpersons'},
{$project: {_id: 0, org_id: '$id', contacts: '$contactpersons', country: 1}},
{$out: 'aggregate_org'}
])
Now you can do a mongoexport of contacts (which is the result of the $unwind of contactpersons) and country.
mongoexport --host localhost --db sample --collection aggregate_org --type=csv --fields country,contacts.firstname,contacts.emailaddress --out D:\info_docs\org.csv

Changing strings in mongodb collection to uppercase

I've searched a lot but still can't find (or understand) the answer. I have a collection in my mongodb database that is called "btest". Inside of that collection I have a list of randomly generated strings (from 1000 to 1000000) that look something like this:
> db.btest.find()
{ "_id" : ObjectId("5818ed42c33b12a7c902cd34"), "0" : 1, "wgickjkwxfimleot" : "r
scjuvarvmvuheom" }
{ "_id" : ObjectId("5818ed42c33b12a7c902cd35"), "0" : 2, "wgickjkwxfimleot" : "t
gdqnegjscsmnjsi" }
{ "_id" : ObjectId("5818ed42c33b12a7c902cd36"), "0" : 4, "wgickjkwxfimleot" : "d
qjvndthelmtqknj" }
{ "_id" : ObjectId("5818ed42c33b12a7c902cd37"), "0" : 5, "wgickjkwxfimleot" : "u
qtmbuhgwxntcixh" }
{ "_id" : ObjectId("5818ed42c33b12a7c902cd38"), "0" : 6, "wgickjkwxfimleot" : "i
rguwjvectjvimjk" }
{ "_id" : ObjectId("5818ed42c33b12a7c902cd39"), "0" : 7, "wgickjkwxfimleot" : "n
sggjpodfvebjumk" }
{ "_id" : ObjectId("5818ed42c33b12a7c902cd3a"), "0" : 8, "wgickjkwxfimleot" : "a
wvjtlxtoqwpdltp" }
I imported these using this command:
mongoimport -d ee_db -c btest --type csv --file "C:\Users\USER\Desktop\Random\projekty java\ee_bulk_insert\src\10000.csv" --headerline
What I want to do is to change all the strings in this collection to uppercase letters. In MySQL I've done the same thing with the "SELECT UCASE(row) FROM btest;" command.
How to achieve the same result in MongoDB? Thanks for all the answers.
You can use an aggregation with a $project using $toUpper to convert string to uppercase and then write the results in a new collection with $out :
db.btest.aggregate(
[{
$project: {
"0": 1,
"wgickjkwxfimleot": { $toUpper: "$wgickjkwxfimleot" }
}
}, {
$out: "results"
}]
)

Mongodb export with conditional logic?

I want to export "street" : "Downstreet 34" But dont export, if the source value is other than 3
Sample 1 JSON
"addresses" : [ {"source" : 3 , "street" : "Downstreet 34"}]
Export "street" : "Downstreet 34"
Sample 2 JSON
"addresses" : [ {"source" : 2 , "street" : "Downstreet 34"}]
Dont export "street" : "Downstreet 34"
mongoexport --db db_name --collection collection_name --query '{source : 3 , street : "Downstreet 34"}' --out output_file.json
This should run - update the query statement as required. Make required simple changes if not working.
db.collection.find(
{ source: 2 },
{ street: 1}
)
Example that you can use to build queries like these are : source
# SQL QUERY
SELECT user_id, status
FROM users
WHERE status = "A"
#mongoDB Query
db.users.find(
{ status: "A" },
{ user_id: 1, status: 1, _id: 0 }
)

mongo export array elements

I would like to export 3 different csv files, here is my document
{
"capacities" : [
{
"size" : "A",
"incoming_parcels" : 27,
"outgoing_parcels" : 0,
"empty_compartments" : 0
},
{
"size" : "B",
"incoming_parcels" : 11,
"outgoing_parcels" : 0,
"empty_compartments" : 8
},
{
"size" : "C",
"incoming_parcels" : 2,
"outgoing_parcels" : 1,
"empty_compartments" : 7
}
]
}
I would like to get all documents where capacities[1] = B and then get all fields - same for all sizes.
Here is my syntax for export :
mongoexport.exe --db name --collection name --type csv --out sizeB.csv -q "{'capacities.1.size': 'B'}" -f size,incoming_parcels,outgoing_parcels,empty_compartments
I've also tried -f capacities.1.size etc
One approach you could take is to use the aggregation framework to filter your documents using the above query as your $match operator and then write the documents returned by the aggregation pipeline to a specified collection using the $out operator. You can then export the data from that aggregation output collection. The following outlines the concept:
db.test.aggregate([
{
"$match": {
"capacities.size": "B"
}
},
{
"$unwind": "$capacities"
},
{
"$match": {
"capacities.size": "B"
}
},
{
"$project": {
"size" : "$capacities.size",
"incoming_parcels" : "$capacities.incoming_parcels",
"outgoing_parcels" : "$capacities.outgoing_parcels",
"empty_compartments" : "$capacities.empty_compartments",
}
},
{
"$out": "capacities_output"
}
])
Export to csv:
mongoexport.exe --db name --collection "capacities_output" --csv > sizeB.csv --fields size,incoming_parcels,outgoing_parcels,empty_compartments