I'm not sure who is at fault here, but we have a column in our users table called last_logged_in_at that we use for sorting. This is in a Rails 2.3 project using Thinking Sphinx with delta indexes enabled.
When a record has delta set to true, it is push to the bottom even if the sorting by last_logged_in_at should put it at the top.
I tried with last_logged_in_at being a datetime, a timestamp and even an integer and the behavior is always the same.
Any ideas why?
The query looks something like:
{:populate=>true,
:match_mode=>:boolean,
:order=>"last_logged_in_at DESC, updated_at DESC",
:per_page=>20,
:with_all=>{:role_id=>17,
:state=>"activated",
:mandator_id=>9,
:profile_active=>true},
:page=>nil}
Sorry, life's crazy busy, hence slow reply.
You're filtering on a string - which Sphinx doesn't currently allow. There are ways around this, though.
Also: You're using :with_all, but :with behaves in exactly the same way in your situation. :with_all is useful when you want to match multiple values on a single attribute. For example, this query will match results where articles have any of the given tag ids:
Article.search :with => {:tag_ids => [1, 2, 3]}
But this next query matches articles with all of the given tag ids:
Article.search :with_all => {:tag_ids => [1, 2, 3]}
I realise neither of these points are directly related to your issue - however, it's best to get the query valid first, and then double-check whether the behaviour is correct or not.
Related
I am new to Rails, and I am given a code, but I do not understand what it means (I am actually just trying to understand the Rails code because I am tasked to use the same logic inside another program)
here is the code
ids = [1, 2, 3]
users = User.where(account_id: ids)
output = Worksheet.where(created_by: users).as_json(only: [:created_at, :id]).group_by_week(week_start: :monday)
{|w| w["created_at"]}
i am not sure if I am following along, but from what i understand, it seems like i am querying the users with id 1, 2, 3, and finding the worksheets that are created by said users, and grouping them by week. However, I do not really understand what the 'only: [:created_at, :id]' does, but I checked through the columns, and there were columns 'created_at' and 'id' inside the worksheet table. Also, I am totally lost about what the below code is about
{|w| w["created_at"]}
and finally, is it possible to let me know what the output of the program would be like? thanks all!
The as_json(only: [:created_at, :id]) part says "convert this result to json but I only want those two columns." Documentation.
The group_by_week(week_start: :monday) takes a block, which is what the { |w| w["created_at"] } part is. It will go through each result from all the previous operations, assign each in turn to w, and then use w["created_at"] for the group_by_week function (for comparison purposes, most likely).
Using thinking_sphinx to fetch data from records. It working fine but facing an issue that not find any to get records on date comparison like created_at greater than or less than. I check their official documentation also Thinking Sphinx
Is thinking sphinx provide that way? If yes then can we do that
It is possible, but it's not entirely obvious.
What you'll need to do is add an extra column in the SELECT clause, and then filter by that. Something along the lines of:
Model.search "pancakes",
:select => "*, IF(created_at > #{1.year.ago.to_i}, 1, 0) AS time_match",
:with => {:time_match => 1}
You will need to have created_at as an attribute in your index file for this to work.
I have a web page where a user can search through documents in a mongoDB collection.
I get the user's input through #q = params[:search].to_s
I then run a mongoid query:
#story = Story.any_of( { :Tags => /#{#q}/i}, {:Name => /#{#q}/i}, {:Genre => {/#{#q}/i}} )
This works fine if the user looks for something like 'humor' 'romantic comedy' or 'mystery'. But if looking for 'romance fiction', nothing comes up. Basically I'd like to add 'and' 'or' functionality to my search so that it will find documents in the database that are related to all strings that a user types into the input field.
How can this be done while still maintaining the substring search capabilties I currently have?Thanks in advance for help!
UPDATE:
Per Eugene's comment below...
I tried converting to case insensitive with #q.map! { |x| x="/#{x}/i"}. It does save it properly as ["/romantic/i","/comedy/i"]. But the query Story.any_of({:Tags.in => #q}, {:Story.in => #q})finds nothing.
When I change the array to be ["Romantic","Comedy"]. Then it does.
How can I properly make it case insensitive?
Final:
Removing the quotes worked.
However there is now no way to use an .and() search to find a book that has both words in all these fields.
to create an OR statement, you can convert the string into an array of strings, and then convert the array of strings into an array of regex and then use the '$in' option. So first, pick a delimeter - perhaps commas or space or you can set up a custom like ||. Let's say you do comma seperated. When user enters:
romantic, comedy
you split that into ['romantic', 'comedy'], then convert that to [/romantic/i, /comedy/i] then do
#story = Story.any_of( { :Tags.in => [/romantic/i, /comedy/i]}....
To create an AND query, it can get a little more complicated. There is an elemMatch function you could use.
I don't think you could do {:Tags => /romantic/i, :Tags => /comedy/i }
So my best thought would be to do sequential queries, even though there would be a performance hit, but if your DB isn't that big, it shouldn't be a big issue. So if you want Romantic AND Comedy you can do
query 1: find all collections that match /romantic/i
query 2: take results of query 1, find all collections that match /comedy/i
And so on by iterating through your array of selectors.
For both basic conditions (like find statements) and the more general where clause, users have the ability to look for any of a group of conditions. For example:
User.find_by_name(["One", "Two", "Three"])
User.find_by_name_and_age(["One", "Two"],[1,2,3])
or
User.where(:bonus_id => [1,2,3])
Their is a slight inconsistance here, though. If you use
User.find_by_bonus_id([nil,1,2])
This will return uses with a bonus id of "nil", as could be expected! However, both the "find_by_...and..." format and "where" format do NOT work this way.
User.where(:bonus_id => [nil,1])
Will return ONLY those Users with a bonus_id of 1.
User.where(:bonus_id => [nil]
will return nothing all!
User.where(:bonus_id => nil)
however, works fine.
As near as I can tell, the where clause (and find_by_and method) collapse their arrays, removing any values that are non-truthy. This is a pretty significant problem for me.
Does anyone know a way to include nils in a where clause array (or a workaround), or am I going to have to end up joining multiple queries together in order to obtain the right behaviour?
Additional Notes:
- Version 3.0.11
- Nils are not actually being dropped, but rather under certain circumstances it is comparing IN (NULL) instead of IS NULL in the SQL. I'm leaving the title as is, since even though it is inaccurate, it's how the problem appears at first when encountered.
I'm not able to reproduce your problem on Rails 3.1.0. What version are you using?
Try this:
User.where(["bonus_id IN (?) OR bonus_id IS NULL", [1,2]])
Will return users where the bonus_id is either 1, 2, or null
So I have two separate queries:
tagged_items = Item.tagged_with(params[:s], :on => :tags)
searched_items = Item.find(:all, :conditions => ["MATCH(title) AGAINST (? IN BOOLEAN MODE)", "*#{params[:s]}*"])
The first tagged_items is using the acts_as_taggable_on plugin to find all the items tagged with XYZ.
The second, searched_items, is used to search the items table for the search term.
So, how could I combine (and avoid duplicates) the results of these two?
Check out named_scope. The second query can be converted to named_scope easily, I'm not sure about the first one, but if you can rewrite it using find, you're home.
http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html
items = (tagged_items + searched_items).unique
But it would be much better if you could fetch them with single query.
This approach...
#items = tagged_items | searched_items
...would make more sense if you're looking to use the results of these queries in a View, instead of working with an Array, and accomplishes the de-duplication as well.