Ruby Mongo Driver - Find_by_Id - ruby

What am I doing wrong here? I know the _id is in the database but I get empty result.
#b = coll.find("_id" => "4db2ebee90036f010b000001")
Thanks

Use this:
coll.find(:_id => BSON::ObjectId('4db2ebee90036f010b000001')).each do |data|
puts data.inspect
end

#b will contain a cursor, not the result. You also need to use an object id proper.
You probably want this:
#b = coll.find_one(:_id => BSON::ObjectId('4db2ebee90036f010b000001'))

With Ruby 1.9.3 and mongoid 3.0.19
#coll = Coll.find( hash["_id"] )
or
#coll = Coll.find( "511296d2dfa18f07fa000009" )
find the record. Will only ever be one, _id is the primary key, it can never be double.

I would use something like first which returns a object since you have bigger problems if your primary id is duplicated in your database. The syntax is depending on your mongo gem version this one is for 2.1.0.
your_id = '4db2ebee90036f010b000001'
db = Client.new([ "localhost:27017" ], :database => "db")
coll = db[:testCollection]
res = coll.find(:_id => BSON::ObjectId(your_id)).first

Using, Ruby version 2.3.1p112, mongo (gem) 2.4.2 and BSON (gem) 4.2.2
The following worked for me
client = Mongo::Client.new(['127.0.0.1:3001'], :database=>'dbname')
collection = client[:users]
user = collection.find({_id:'XY3h5R7aJkh5FxFhJ'}).first

Related

Get RethinkDB query working in Ruby on Rails

I have a ReQL query...
r.db('development').table('responses').filter({
survey_id: 9
}).concatMap(r.row.getField('numerical_answers')).filter({
type: 'CustomerEffortAnswer'
}).sum('number')
...that I would like to get working in NoBrainer because I can't seem to get it working on Ruby on Rails. When I try to run just the ReQL in Rails like so...
NoBrainer.run do |r|
return_count = r.db('development').table('responses').filter({ survey_id: id }).concatMap(r.row.getField('numerical_answers')).filter({type: 'CustomerEffortAnswer'}).sum('number')
end
...I get the error:
Sorry, r.row is not available in the ruby driver. Use blocks instead.
Needed to convert the code over to Ruby language:
return_count = NoBrainer.run do |r|
r.db('development').table('responses')
.filter({:survey_id => 9})
.concat_map { |doc| doc[:numerical_answers] }
.filter({:type => 'CustomerEffortAnswer'})
.sum('number')
end

Ruby Mongo DB multiple records of same value

I'm new to MongoDB and databases in general. I'm using Ruby and I would like to query against a specific UUID in the database.
The ID is stored as _id and the value is '101b437a-be16-44f6-b0b0-0201cdee6510'
I have the following that usually queries my database:
field = '_id:'
value = 101b437a-be16-44f6-b0b0-0201cdee6510
def query_field(field,value)
query = {#{field}: value}
#result = #mongo_interface.get(query)
expect(#result.count).to be >= 1
puts "Number of matched values: #{#result.count}"
end
def get(param_hash, collection_name = nil)
col_name = (collection_name.nil? || collection_name.empty?) ? #collection : collection_name
#docs = #db[col_name].find(param_hash)
end
When I look within the _id field, I'm assuming it's stored as some sort of binary key and thus isn't found using my search.
Is there some conversion I could/should do to make the query above work?
Thank you.
Using an ODM like Mongoid will ease your pain. Add it to your Gemfile:
gem 'mongoid'
and run bundle install. Make sure you skimmed through the installation guide to add all the necessary configs.
Then include the following line to your model/class, say:
class Product
include Mongoid::Document
...
end
You'll be able to query the records like Product.find(id) right after.

Mongo Ruby Driver #find() on Specified field Values

Ruby: ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]
RubyGem: mongo (2.0.4)
I need help querying a MongoDB database with their gem and updating the appropriate fields.
EDIT: I'm trying to loop over documents of a Mongo database, pull down the values of specific fields in those documents, and update them later in the script.
Objectives
Query the database for documents where the field partner_id is "partner" and where the field state is "provisioned", and return only the values under the _id and config fields.
After this point, I'll be iterating over each document, generating a password, and updating another database.
Update the database with the newly generated password to each documents config field.
I'm at my wit's end as I've seen about half a dozen different way to write the syntax, and the documentation is little help unless I already knew how to do these things. Any assistance would be greatly appreciated!
#!/usr/bin/env ruby
require 'json'
require 'net/http'
require 'mongo'
# Fetch the addons database URI and connect.
db_uri = ENV['DATABASE_URI']
client = Mongo::Client.new(db_uri)
# Connect to the needed collection and pull down each document to be looped over individually.
# **Having trouble getting this to work. The result is just '= []' - don't know what I'm doing wrong.
client[:collection].find("partner_id" => "partner", "state" => "provisioned", :fields => ["_id", "config"]).each {
# Need something here to pull down the values from each document's '_id' and 'config' fields and assign them to variables.
user_id =
user_config =
user_config = JSON.parse(user_config)
# ...generating password and updating other database...
# Convert the Hash of the user's new configuration into JSON, and update the original database with it.
# Not sure if any of this is correct. When querying to check, the database doesn't seem to be updated.
user_config = user_config.to_json
client[:collection].update(
{"_id" => user_id},
{'$set' => {
"config" => user_config
}
}
)
}
end
return
You're not finding anything because this:
:fields => ["_id", "config"]
argument to find isn't specifying the fields you want, find just sees that as a third document field to look for. Your documents probably don't have a field called field whose value is an array of those strings so the query silently finds nothing at all.
If you want to limit your query, you need to use projection:
client[:collection].find("partner_id" => "partner", "state" => "provisioned")
.projection('_id' => 1, 'config' => 1)
.each { |doc| ... }
Then inside the each block the doc will be a Hash so you can say:
user_id = doc['user_id']
user_config = doc['user_config']
If I'm reading your code right, the user_config should be a Hash already so you probably won't need to parse it yourself.

MongoDB + Ruby. How to access document properties?

I want to try Mongo with Ruby. I connected, selected collection and I can query data from MongoDB.
irb(main):049:0> coll.find_one({:x=>4})
=> #<BSON::OrderedHash:0x3fdb33fdd59c {"_id"=>BSON::ObjectId('4f8ae4d7c0111ba6383cbe1b'), "x"=>4.0, "j"=>1.0}>
irb(main):048:0> coll.find_one({:x=>4}).to_a
=> [["_id", BSON::ObjectId('4f8ae4d7c0111ba6383cbe1b')], ["x", 4.0], ["j", 1.0]]
But how to access propeties, when I retrieve BSON hash? I need something like this:
data.x
=> 4
to_hash method gives me the same BSON::OrderedHash... :(
When you say coll.find_one({:x=>4}), you get a BSON::OrderedHash back that you access like a normal Hash:
h = coll.find_one(:x => 4)
puts h['x']
# 4 comes out unless you didn't find anything.
If you use a full find instead of find_one, you get a MongoDB::Cursor which is an Enumerable so you can iterate it like any other collection; the cursor will return BSON::OrderedHash instances as you iterate so you can do things like this:
cursor = coll.find(:thing => /stuff/)
cursor.each { |h| puts h['thing'] }
things = cursor.map { |h| h['thing'] }
If you wanted objects instead of Hashes then you'd have to wrap the MongoDB::Cursor and BSON::OrderedHash instances with object yourself (possibly via Struct).
Mongodb find_one method returns hash object, find method returns cursor object.
Cursor object can be iterated and then is possible to extract the answer in a normal hash.
require 'rubygems'
require 'mongo'
include Mongo
client = MongoClient.new('localhost', 27017)
db = client.db("mydb")
coll = db.collection("testCollection")
coll.insert({"name"=>"John","lastname"=>"Smith","phone"=>"12345678"})
coll.insert({"name"=>"Jane","lastname"=>"Fonda","phone"=>"87654321"})
cursor = coll.find({"phone"=>"87654321"})
answer = {}
cursor.map { |h| answer = h }
puts answer["name"]

Preventing SQL Injection/Good Ruby method

What is a good method in Ruby to prevent SQL Injection?
in straight up ruby? use prepared statements:
require 'mysql'
db = Mysql.new('localhost', 'user', 'password', 'database')
statement = db.prepare "SELECT * FROM table WHERE field = ?"
statement.execute 'value'
statement.fetch
statement.close
Not just in Ruby - bind your parameters (be it in the database, or in your client code).
Check out the guide they have up on this: http://guides.rubyonrails.org/security.html#injection
Basically, you want to use bind variables in your models to find data, rather than inline parameters..
Model.find(:first, :conditions => ["login = ? AND password = ?", entered_user_name, entered_password])
According to http://ruby.railstutorial.org/ you can prevent Cross Site Request Forgery by inserting the
<%= csrf_meta_tags %>
tag in the header of app/views/layouts/application.html.erb.
Direct link of example
This thread references:
http://www.ruby-forum.com/topic/90258#new
http://www.ruby-forum.com/topic/82349#143790
ActiveRecord's find() method has built in ways to avoid SQL injection by
using the format
> :conditions => [ "user_name = ?", user_name]
Is there any such system for escaping injection in order? It seems to
only take a string and feed it to the SQL statement. This causes a
vulnerability when using params to set : order as in this function:
def list
sort_by = params[:sort_by]
#book_pages, #books = paginate :books,
:order => sort_by,
:per_page => 10
end
We've tried a few methods to sanitize sort_by such as order => ['?',
sort_by] but it just passes that to the SQL statement like a flattened
array. The 'escaping magic' does not work for order. Should I use
gsub! to sanitize params[:sort_by]?

Resources