Mongodb, osm street maps, unique users - mongodb

I imported a json file into my database, and the db itself works.
If use
print db.points.find_one()
my output looks like :
{u'id': u'342902', u'_id': ObjectId('555af76a029d3b1b0ff9a4be'), u'type': u'node', u'pos': [48.9979746, 8.3719741], u'created': {u'changeset': u'7105928', u'version': u'4', u'uid': u'163673', u'timestamp': u'2011-01-27T18:05:54Z', u'user': u'Free_Jan'}}
which is exactly what I want it to be. But if I want to get the number of distinct users:
print db.points.distinct({"created.user"}).length
I get the error:
TypeError: key must be an instance of basestring
which suggests that what I was searching for is not there (it clearly is as shown above). What am I missing here ?

You have a syntax error in your distinct clause - it should be .distinct("created.user") instead of .distinct({"created.user"}).
See the MongoDB documentation for distinct.
Edit: To return the length, therefore, something like:
print len(db.points.distinct("created.user"));
... or:
print db.points.distinct("created.user").__len__();
See this answer for getting the size of a list in Python.
Caveat: I'm no Python expert so the length bit might not be perfect...

I was facing the same problem.
print len(db.points.distinct("created.user")) works.
However,
print db.points.distinct("created.user").__len__();
does not.
The reason for the error is the braces:
db.points.distinct({"created.user"})
should read
db.points.distinct("created.user")
Also, '.length' is a mongo bash method. In pymongo, you use 'len()'. That is:
db.points.distinct({"created.user"}).length
should read
print len(db.points.distinct("created.user"))
unless you are using mongo bash/shell.

Related

How to parse the CAP id instead of a hashed value with Weather::NOAA::Alert in Perl

Thanks to the accepted answer in the following solution, I'm now able to extract most of the values I need from NOAA alerts: perl Data::Dumper to extract key values
I would like to parse the "CAP id" as well, however when I try, I receive a hashed value instead of the URL.
For example, using the previously mentioned thread, what I would like to parse is:
http://alerts.weather.gov/cap/wwacapget.php?x=TX12516CBE9400.FloodWarning.12516CC068C0TX.MAFFLWMAF.f21e7ce7cf8e930ab73a110c4d912576
What I get instead: HASH(0x26384c0)
I imagine this is only possible by modifying alert.pm:
https://github.com/mikegrb/Weather-NOAA-Alert/blob/master/lib/Weather/NOAA/Alert.pm and if I've read enough into the issue, it may be on account of XML::Simple?
Typically, I would use XPath to parse XML like data, but for this ATOM format I'm lost.
Ultimately, I'm simply looking to add the parsed variables to an SQL database. With NOAA looking to transition from CAP v1.1 to v1.2 (when, I have no clue), perhaps I should be looking at using something else.
In your previous code, you can get the single key of the hashref $events->{'TXC301'} like this:
my #keys = keys %{$events->{'TXC301'}}
my $alert_url = $keys[0]
Now $alert_url should hold the URL you were mentioning.
Does this answer your question?

Get specific data form Xapian database with Perl

I'm writing a perl script to retrieve search results from a Xapian database.
I uses the Search::Xapian module and tried the basic Xapian Query Example. This basic program allow to make a query and get a array of results sorted by relevancy. My problem is that the get_data() method return the whole datas from the document (url, filname, abstract, author, ...) mixed together as a string.
I searched in the CPAN module for a method to get each data one by one but I didn't find it.
Is it possible to get the filename, url, author, ... one by one to put them in a specific variable ?
You've not posted the code to produce this, or details of your setup. See the simplesearch.pl example, rather than print it out, assign what you want to a variable:
# Display the results.
printf "%i results found.\n", $mset->get_matches_estimated();
printf "Results 1-%i:\n", $mset->size();
foreach my $m ($mset->items()) {
printf "%i: %i%% docid=%i [%s]\n", $m->get_rank() + 1, $m->get_percent(), $m->get_docid(), $m->get_document()->get_data();
}

How to make the result displayed as multiply line NOT one line for mongodb [duplicate]

Is there a way to tell Mongo to pretty print output? Currently, everything is output to a single line and it's difficult to read, especially with nested arrays and documents.
(note: this is answer to original version of the question, which did not have requirements for "default")
You can ask it to be pretty.
db.collection.find().pretty()
You can add
DBQuery.prototype._prettyShell = true
to your file in $HOME/.mongorc.js to enable pretty print globally by default.
(note: this is answer to the updated question)
You can just do this on the CLI:
echo DBQuery.prototype._prettyShell = true >> ~/.mongorc.js
And it's always going to output pretty results.
Since it is basically a javascript shell, you can also use toArray():
db.collection.find().toArray()
However, this will print all the documents of the collection unlike pretty() that will allow you to iterate.
Refer: http://docs.mongodb.org/manual/reference/method/cursor.toArray/
Oh so i guess .pretty() is equal to:
db.collection.find().forEach(printjson);
Give a try to Mongo-hacker(node module), it alway prints pretty.
https://github.com/TylerBrock/mongo-hacker
More it enhances mongo shell (supports only ver>2.4, current ver is 3.0), like
Colorization
Additional shell commands (count documents/count docs/etc)
API Additions (db.collection.find({ ... }).last(), db.collection.find({ ... }).reverse(), etc)
Aggregation Framework
I am using for while in production env, no problems yet.
Got to the question but could not figure out how to print it from externally-loaded mongo. So:
This works is for console: and is prefered in console, but does not work in external mongo-loaded javascript:
db.quizes.find().pretty()
This works in external mongo-loaded javscript:
db.quizes.find().forEach(printjson)
Check this out:
db.collection.find().pretty()

Where is my associative array and how do I access it using Perl DBI?

I'm working with perl, and using DBI. Up to now, I've been using ->fetchall_arrayref to get the results of a database query, and just accessing the array by numeric keys. However, I much prefer to be able to access records by the field names (associative fetch) than numeric.
How do I do this, and what is the correct syntax for accessing the keys?
I would prefer something like:
$data[0]['name']
Instead of:
$data[0][1]
Working Solution
my %data;
#{$data{$id}}{('name')} = 'something';
Read the DBI docs. Particularly, fetchall_hashref.
And you should also learn Perl syntax, as it's not the same as PHP.
You can use selectall_arrayref for this. Here's example from the DBI manpage:
You may often want to fetch an array of rows where each row is stored as a hash.
That can be done simple using:
my $emps = $dbh->selectall_arrayref(
"SELECT ename FROM emp ORDER BY ename",
{ Slice => {} }
);
foreach my $emp ( #$emps ) {
print "Employee: $emp->{ename}\n";
}
If you do fetchall_hashref() then you get the hash you are looking for. The keys will be the field names from the database. I am a little late, and Joe got it, but it will be.
$data->{0}->{'field'};

After querying DB I can't print data as well as text anymore to browser

I'm in a web scripting class, and honestly and unfortunately, it has come second to my networking and design and analysis classes. Because of this I find I encounter problems that may be mundane but can't find the solution to it easily.
I am writing a CGI form that is supposed to work with a MySQL DB. I can insert and delete into the DB just fine. My problem comes when querying the DB.
My code compiles fine and I don't get errors when trying to "display" the info in the DB through the browser but the data and text doesn't in fact display. The code in question is here:
print br, 'test';
my $dbh = DBI->connect("DBI:mysql:austinc4", "*******", "*******", {RaiseError => 1} );
my $usersstatement = "select * from users";
my $projstatment = "select * from projects";
# Get the handle
my $userinfo = $dbh->query($usersstatement);
my $projinfo = $dbh->query($projstatement);
# Fetch rows
while (#userrow = $userinfo->fetchrow()) {
print $userrow[0], br;
}
print 'end';
This code is in an if statement that is surrounded by the print header, start_html, form, /form, end_html. I was just trying to debug and find out what was happening and printed the statements test and end. It prints out test but doesn't print out end. It also doesn't print out the data in my DB, which happens to come before I print out end.
What I believe I am doing is:
Connecting to my DB
Forming a string the contains the command/request to the DB
Getting a handle for my query I perform on the DB
Fetching a row from my handle
Printing the first field in the row I fetched from my table
But I don't see why my data wouldn't print out as well as the end text. I looked in DB and it does in fact contain data in the DB and the table that I am trying to get data from.
This one has got me stumped, so I appreciate any help. Thanks again. =)
Solution:
I was using a that wasn't supported by the modules I was including. This leads me to another question. How can I detect errors like this? My program does in fact compile correctly and the webpage doesn't "break". Aside from me double checking that all the methods I do use are valid, do I just see something like text not being displayed and assume that an error like this occurred?
Upon reading the comments, the reason your program is broken is because query() does not execute an SQL query. Therefore you are probably calling an undefined subroutine unless this is a wrapper you have defined elsewhere.
Here is my original posting of helpful hints, which still apply:
I hope you have use CGI, use DBI, etc... and use CGI::Carp and use strict;
Look in /var/log/apache2/access.log or error.log for the bugs
Realize that the first thing a CGI script prints MUST be a valid header or the web server and browser become unhappy and often nothing else displays.
Because of #3 print the header first BEFORE you do anything, especially before you connect to the database where the script may die or print something else because otherwise the errors or other messages will be emitted before the header.
If you still don't see an error go back to #2.
CGIs that use CGI.pm can be run from a command line in a terminal session without going through the webserver. This is also a good way to debug.