Sphinx Sorting not working - sorting

in my table definition I have multiple int fields i.e. id, verified (this is int not bool) and filesize. I am able to sort by id but unable to sort by verified or filesize.
// Include Sphinx API file
$s = new SphinxClient;
$s->setServer("localhost", 9312);
$s->setMaxQueryTime(300);
$s->SetSortMode(SPH_SORT_EXTENDED, '#id ASC');
$result = $s->query("test");
The above code works fine but instead if I use $s->SetSortMode(SPH_SORT_EXTENDED, '#verified ASC'); or $s->SetSortMode(SPH_SORT_EXTENDED, '#filesize ASC'); it's not working.
I tried something like
$s->SetSortMode(SPH_SORT_EXTENDED, '#id ASC, #verified ASC, #filesize ASC');
And my Config file (partial) is like
sql_query = \
SELECT id, title, verified, filesize \
FROM domains
sql_attr_uint = id
sql_attr_uint = verified
sql_attr_uint = filesize
sql_query_info = SELECT * FROM documents WHERE id=$id
After I edited my config file I used the following command to reindex the data
sudo indexer item --config /etc/sphinxsearch/sphinx.conf --rotate --print-queries
And, then restarted Sphinx by using sudo service sphinxsearch restart but still no luck.
I am need to sort the results by verified and filesize. How can I achieve it?
Thanks

Remove this line:
sql_attr_uint = id
id should not be declared as an attribute. Its not, its the document id :)
I think sphinx is just ignoring this line automatically; but its presence, just leads to confusion (because it does nothing)
But otherwise should try
$s->SetSortMode(SPH_SORT_EXTENDED, 'verified ASC');
or
$s->SetSortMode(SPH_SORT_EXTENDED, '#id ASC, verified ASC, filesize ASC');
# is a prefix for special 'internal' values. id is considered special (its the document id), so should have the prefix. But normal attributes SHOULDN'T have it.

Related

Project a single column of a table filtered by tag from act as taggale

Currently the only way I know to sub select in rails is with arel,
for exmaple -
sub = x.where(y:'x').project(:id)
select = a.where(a[:x_id].in(sub))
question is,
if x is using the acts as taggable on gem and need to filtered by a specific tag, use with tagged_with method.
How can I still achive same database efficiency, it looks like the tagged with method override the projection.
thanks,
You don't need Arel to build sub selects in Rails:
sub = X.where(y: 'x')
select = A.where(x_id: sub)
generates the following SQL, assuming A's table name is as and X's is xs:
SELECT "as".* FROM "as" WHERE "as"."x_id" IN (SELECT "xs"."id" FROM "xs" WHERE "xs"."y" = 'x')
Testing with tagged_with worked: A.where(x_id: X.tagged_with('my_tag')) generates the expected SQL, at least for Rails 5.1, version on which I've tested.
Edit
You can specify the column used inside the subselect if needed. If you don't specify it, the primary key column is the default:
sub = X.where(y: 'x').select(:x_y_id)
select = A.where(x_id: sub)
will generate the following SQL:
SELECT "as".* FROM "as" WHERE "as"."x_id" IN (SELECT "xs"."x_y_id" FROM "xs" WHERE "xs"."y" = 'x')

For table cmdb_rel_ci, I want to retrieve unique parent.sys_class_name with count for "type=In Rack::Rack contains"

For table cmdb_rel_ci, I want to retrieve unique parent.sys_class_name with count for "type=In Rack::Rack contains". I am doing practice in out of the box instance.
At table level URL is as below:
URL
I want to retrieve result from above URL with my below script.
var count = new GlideAggregate('cmdb_rel_ci');
count.addQuery('type','e76b8c7b0a0a0aa70082c9f7c2f9dc64');// sys_id of type In Rack::Rack contains e76b8c7b0a0a0aa70082c9f7c2f9dc64
count.addAggregate('COUNT', 'parent.sys_class_name');
count.query();
while(count.next()){
var parentClassName = count.parent.sys_class_name.toString();
var parentClassNameCount = count.getAggregate('COUNT','parent.sys_class_name');
gs.log(parentClassName + " : " + parentClassNameCount );
}
The issue is I am getting parentClassName empty.
Try this instead:
var parentClassName = count.getValue("parent.sys_class_name")
Since it's a GlideAggregate query (instead of GlideRecord), the query being issued isn't returning all of the fields on the target table. With GlideRecord, dot-walking through a reference field (e.g. parent.sys_class_name) automatically resolves that referenced record to provide access to its field values. This is made possible by the fact that the driving/original query brought back the value of the parent field. This is not happening with GlideAggregate. The query in this case basically looks like:
SELECT cmdb1.`sys_class_name` AS `parent_sys_class_name`, count(*)
FROM (cmdb_rel_ci cmdb_rel_ci0 LEFT JOIN cmdb cmdb1 ON cmdb_rel_ci0.`parent` = cmdb1.`sys_id` )
WHERE cmdb_rel_ci0.`type` = 'e76b8c7b0a0a0aa70082c9f7c2f9dc64'
GROUP BY cmdb1.`sys_class_name`
ORDER BY cmdb1.`sys_class_name`
So, you actually have access specifically to that dot-walked sys_class_name that's being grouped, but not through the dot-walk. The call to getValue("parent.sys_class_name") is expectedly resolved to the returned column aliased as parent_sys_class_name.
That being said, what you're doing probably should also work, based on user expectations, so you've not done anything incorrect here.

CodeIgniter UPDATE and LIMIT

I know this question has been posted already before Update with limit 1 in codeigniter use active record
But it seems combining UPDATE and LIMIT using Active Record doesnt work on my side. It will still update all record based on the WHERE clause. I'm currently using CodeIgniter 3.0.6. Is this a bug from CodeIgniter already?
screenshot of the query
You cannot directly add limit in update query. I get an alternative way. Firstly you get one row by where query and then run the update query with using fetching row unique key like unique auto increment id.
$singleInfo = $this->db->get_where($tbl, array('user_id'=>1));
$this->db->update($tbl,array('username'=>'FredSmith'),array('user_id'=>$singleInfo->id));
Well I fired up CI 3.0.6 and used this as a demonstration, as we cannot see your setup.
public function db_update_test_with_limit(){
$tbl = 'users';
// Use Chaining - Works
$this->db
->where('user_id',1)
->limit(1)
->update($tbl,array('username'=>'FredSmith'));
echo $this->db->last_query();
// Use discrete calls - Works
$this->db->where('user_id',1);
$this->db->limit(1);
$this->db->update($tbl,array('username'=>'FredSmith'));
echo '<br>';
echo $this->db->last_query();
}
And the results for both are...
UPDATE `users` SET `username` = 'FredSmith' WHERE `user_id` = 1 LIMIT 1
UPDATE `users` SET `username` = 'FredSmith' WHERE `user_id` = 1 LIMIT 1
So if you are doing the same thing and getting different results, then something funky is going on.
If you use this as a test and massage it to suit your situation, does it work or not?

Write query which run on array by considring sub query in Parse

I need to write a query in such way that the array(collection) is contain only sub query objects.
Suppose we have the two tables as follows:
TableA:
objectId, name
TableB:
objectId, names[array of name: parse pointer collection]
Here is my code which I tried:
// sub query
var subQuery = new Parse.Query('TableA');
subQuery.doesNotExist('name');
// main query
var query = new Parse.Query('TableB');
query.exists("names");
//query.containsAll("names", subQuery); // this means names should contain all subQuery, so this is not use full for me.
query.matchesQuery("names", subQuery);
This code is running fine, but this is not working as I want and also not showing the any error.
It seems that you don't need a subquery per se, but rather to first query your list of names, and then use that in your main query. What you seem to be looking for is: containedIn( key, values ) , as in:
query.containedIn("name", namesFromFirstQuery)

How to write out data field as Ruby code?

I store sql like select * from classes where owner_id = #{#current_user.id} in my database.
Can any one tell me how write out the above sql as ruby code so the #{#current_user.id} can be replaced dynamically as the id of the current signed in user?
Without any security/input validation in mind, you could do like this:
q_template = "select * from classes where owner_id = %s"
and to "populate" it, you could do like this:
sample_input = "40"
new_query = q_template % sample_input
# this will create q_template = "select * from classes where owner_id = 40"
If you end up using this, make sure you check your input for malicious things before feeding it to the database.

Resources