how to properly create a between clause on mongo mapper - ruby-on-rails

I'm trying to create a query like this
User.find_each(created_at: [1.day.ago.utc, Date.now]) do |user|
but that didn't worked. Always return 0 users, but I do have users created in the 1 day timeframe. I believe I'm doing this query wrong, but the mongo mapper documentation says nothing about this.
Any ideas?

Activate the profiling with db.setProfilingLevel(2).
Rerun your code.
Get the query you sent to MongoDB in the system.profile collection.
Run this query in the mongoshell to check what's wrong.
Update your code to send the command you want.

Related

Clone a mongodb collection from within Rails Mongoid

I am trying to implement this solution in rails, using the collection aggregate method, to clone an entire collection within the same database.
In mongo shell, this works perfectly, and a cloned collection is created successfully:
db.source_collection.aggregate([ { $match: {} }, { $out: "target_collection" } ])
The rails-mongoid alternate, according to my research, should be this, which runs without errors:
SourceCollection.collection.aggregate({"$match" => {}, "$out" => "target_collection"})
#<Mongo::Collection::View::Aggregation:0x000000055bced0 #view=#<Mongo::Collection::View:0x44951600 namespace='DB_dev.source_collection' #filter={} #options={}>, #pipeline={"$match"=>{}, "$out"=>"target_collection"}, #options={}>
I also tried with an array
SourceCollection.collection.aggregate([{"$match" => {}}, {"$out" => "target_collection"}])
#<Mongo::Collection::View::Aggregation:0x000000054936d0 #view=#<Mongo::Collection::View:0x44342320 namespace='DB_dev.source_collection' #filter={} #options={}>, #pipeline=[{"$match"=>{}}, {"$out"=>"target_collection"}], #options={}>
UPDATE
This simplest syntax also works in Mongo console:
db.source_collection.aggregate( { $out: "target_collection" } )
But the respective syntax does not seem to work in Ruby:
SourceCollection.collection.aggregate({"$out" => "target_collection"})
Unfortunately, although there are no errors, the collection is not created.
Any clues as to the way I can make this happen?
Mongo gem version 2.5.3
Update2
Apparently $out is not considered in the pipeline, thus rendering the aggregation invalid.
This can be fixed with code... I am looking for a module/class/method override, as contacting mongodb issue tracking system for a change request might not be as quick..
UPDATE - FINAL
This issue has been solved, by help of Thomas R. Koll (thank you).
I add an update to post the response I got from the ticketing service of MongoDB, which pretty much describes Thomas's solution.
The reason you're not seeing the results without count is that the
aggregate method returns a lazy cursor; that is, the query does not
execute until the return value of aggregate is iterated over.
Calling count is one way to do this. This is the same behavior
you'll see if you call find or if you call aggregate without
specifying $out; the difference is that $out has an side-effect
beyond just returning the results, so it's more obvious when exactly
it occurs.
Found the solution, and I have to explain a few thigs:
This returns a Mongo::Collection::View::Aggregation object, it won't send a query to the database
User.collection.aggregate({"$out": "target_collection"})
Only when you call a method like count or to_a on the aggregation object it will be sent to the server, but if you pass a hash you'll get an error, so the pipeline has to be an array of hashes to work
User.collection.aggregate([{"$out": "target_collection"}]).count

neo4jrb how to reset transaction timeout of an open transaction

Currently using neo4j-community-2.1.7
I understand that the facility has been included in this version.
Have been unable to find any reference to it in the ruby docs.
Would appreciate it very much if I may have some direction on how to reset the timeout using neo4jrb.
Regards
Ross
I am unaware of a way to reset the transaction timeout of an open transaction. Maybe someone more familiar with transactions in the Java API can clarify.
If you want to change the transaction timeout length at boot, that's handled in neo4j-server.properties as described at http://neo4j.com/docs/stable/server-configuration.html.
Within Neo4j-core, if using Neo4j-community or Neo4j-enterprise (and therefore Neo4j Embedded) the code suggests that you can specify a config file by giving a third argument to Neo4j::Session.open, a hash that contains config options. That method, if given :embedded_db as its first arg, will call Neo4j::Embedded#initialize and give that hash as an argument. If you do something like this:
Neo4j::Session.open(:embedded_db, 'path_to_db', properties_file: 'path_and_filename_to_neo4j-server.properties')
It will eventually use that properties file:
db_service.loadPropertiesFromFile(properties_file) if properties_file
This is not demonstrated in any of the specs, unfortunately, but you can see it in the initialize and start methods at https://github.com/neo4jrb/neo4j-core/blob/230d69371ed6bf39297786155ef4f3b1831dac08/lib/neo4j-embedded/embedded_session.rb.
RE: COMMENT INFO
If you're using :server_db, you don't need to include the neo4j-community gem. It isn't loaded, it isn't compatible with Neo4j in Server mode.
That's the first time I've seen the link you provided, good to know that's there. We don't expose a way to do that in Neo4j.rb and won't because it would require some threading magic that we can't support. If you want to do it manually, the best I can tell you is that you can get a current transaction ID this way:
tx = Neo4j::Transaction.new
# do stuff and before your long-running query...
tx.resource_data[:commit].split('/')[-2]
That will return the transaction number that you can use in POST as described in their support doc.
If you'd like help troubleshooting your long-running Cypher query, I'm sure people on SO will help.

Rails: Getting column value from query

Seems like it should be able to look at a simple tutorial or find an aswer with a quick google, but I can't...
codes = PartnerCode.find_by_sql "SELECT * from partner_codes where product = 'SPANMEX' and isused = 'false' limit 1"
I want the column named code, I want just the value. Tried everything what that seems logical. Driving me nuts because everything I find shows an example without referencing the actual values returned
So what is the object returned? Array, hash, ActiveRecord? Thanks in advance.
For Rails 4+ (and a bit earlier I think), use pluck:
Partner.where(conditions).pluck :code
> ["code1", "code2", "code3"]
map is inefficient as it will select all columns first and also won't be able to optimise the query.
You need this one
Partner.where( conditions ).map(&:code)
is shorthand for
Partner.where( conditions ).map{|p| p.code}
PS
if you are often run into such case you will like this gem valium by ernie
it gives you pretty way to get values without instantiating activerecord object like
Partner.where( conditions ).value_of :code
UPDATED:
if you need access some attribute and after that update record
save instance first in some variable:
instance=Partner.where( conditions ).first
then you may access attributes like instance.code and update some attribute
instance.update_attribute || instance.update_attributes
check documentation at api.rubyonrails.org for details

Search in Rails using find

#user_post = Post.find(:all,:conditions => ["content LIKE ?", "%#{params[:query]}%"])
This particular statement returning nil even though there exists a record in the database. Where could be the problem?
Please help me out.
Have you verified that the parameters are being passed in correctly? When a query isn't returning expected results it is almost always because the query you think you are executing isn't really the query that you are executing. Take a look at your log files to verify the that the query is correct.
have you tried running resulting query in mysql console? if you do have result then keep debugging, error is somewhere between controller action and rendered view. maybe you're loading result in before_filter which is not executed for your action?

Saving updates to objects in rails

I'm trying to update one of my objects in my rails app and the changes just don't stick. There are no errors, and stepping through with the debugger just reveals that it thinks everything is updating.
Anyway, here is the code in question...
qm = QuestionMembership.find(:first, :conditions => ["question_id = ? AND form_id = ?", q_id, form_id])
qm.position = x
qm.save
For reference sake, QuestionMembership has question_id, form_id, and position fields. All are integers, and have no db constraints.
That is basically my join table between Forms and Questions.
Stepping through the code, qm gets a valid object, the position of the object does get changed to the value of x, and save returns 'true'.
However, after the method exits, the object in the db is unchanged.
What am I missing?
You may not be finding the object that you think you are. Some experimenting in irb might be enlightening.
Also, as a general rule when changing only one attribute, it's better to write
qm.update_attribute(:position, x)
instead of setting and saving. Rails will then update only that column instead of the entire row. And you also get the benefit of the data being scrubbed.
Is there an after_save?
Is the correct SQL being emitted?
In development log, you can actually see the sql that is generated.
For something like this:
qm = QuestionMembership.find(:first, :conditions => ["question_id = ? AND form_id = ?", q_id, form_id])
qm.position = x
qm.save
You should see something to the effect of:
SELECT * FROM question_memberships WHERE question_id=2 AND form_id=6 LIMIT 1
UPDATE question_memberships SET position = x WHERE id = 5
Can you output what sql you are actually seeing so we can compare?
Either update the attribute or call:
qm.reload
after the qm.save
What is the result of qm.save? True or false? And what about qm.errors, does that provide anything that makes sense to you? And what does the development.log say?
I have run into this problem rather frequently. (I was about to say consistently, but I cannot, as that would imply that I would know when it was about to happen.)
While I have no solution to the underlying issue, I have found that it seems to happen to me only when I am trying to update mysql text fields. My workaround has been to set the field to do something like:
qm.position = ""
qm.save
qm.position = x
qm.save
And to answer everyone else... when I run qm.save! I get no errors. I have not tried qm.save?
When I run through my code in the rails console everything works perfectly as evidenced by re-finding the object using the same query brings the expected results.
I have the same issue when using qm.update_attribute(... as well
My workaround has gotten me limping this far, but hopefully someone on this thread will be able to help.
Try changing qm.save to qm.save! and see if you get an exception message.
Edit: What happens when you watch the log on the call to .save!? Does it generate the expected SQL?
Use ./script/console and run this script.. step by step..
see if the position field for the object is update or not when you run line 2
then hit qm.save or qm.save!... to test
see what happens. Also as mentioned by Tim .. check the logs
Check your QuestionMembership class and verify that position does not have something like
attr_readonly :position
Best way to debug this is to do
tail -f log/development.log
And then open another console and do the code executing the save statement. Verify that the actual SQL Update statement is executed.
Check to make sure your database settings are correct. If you're working with multiple databases (or haven't changed the default sqlite3 database to MySQL) you may be working with the wrong database.
Run the commands in ./script/console to see if you see the same behavior.
Verify that a similar object (say a Form or Question) saves.
If the Form or Question saves, find the difference between the QuestionMembership and Form or Question object.
Turns out that it was emitting the wrong SQL. Basically it was looking for the QuestionMembeship object by the id column which doesn't exist.
I was under the impression that that column was unnecessary with has_many_through relationships, although it seems I was misguided.
To fix, I simply added the id column to the table as a primary key. Thanks for all the pointers.

Resources