Sphinx morphology and suggestion not working together - sphinx

I've enabled morphology with lemmatizer and it returns correct result for this situation:
I have not journalist keyword indexed and instead the journalists exists. The morphology helps us to search by journalist because it is the singular form of existed keyword.
But when I want to call suggestion on the journalist keyword, it will not return this word for suggestion because it doesn't exist and the morphology has not been enabled on it.
The result will be these existed keywords:
array:4 [▼
0 => {#603 ▼
+"suggest": "journalism"
+"distance": "1"
+"docs": "2"
}
1 => {#604 ▼
+"suggest": "journalists"
+"distance": "1"
+"docs": "1"
}
2 => {#605 ▼
+"suggest": "journals"
+"distance": "2"
+"docs": "1"
}
3 => {#608 ▼
+"suggest": "journeys"
+"distance": "4"
+"docs": "2"
}
]
Is it an issue with sphinx or my application?

Related

geoNear with Pagination and sorting on created_at

I´m having an App with the capability of listing articles within a user specified location + radius surrounding. See ruby code with mongo query below.
For Web App, it uses pagination based on "last item" (min_distance) and "excluded_ids" in combination with "limit", what I believe to be the most performant and also better than "limit" and "skip". This solution approach supports "previous page" and "next page". For "jump to page" it makes use of the combination of "limit" and "skip".
geoNear by nature sorts by "distance".
New requirement is to have, additionally, sort by "created_at" (user toggle).
My question:
For sort by "created_at" to work, will it be sufficient to add sort into the query? I´m afraid this won´t work for the current implemented pagination approach and I will need to somehow rewrite to have "last item" based on "created_at", rather than on "min_distance".
Can someone tell for sure how Mongo handles internally the sort and if simply adding sort for created_at will work with this type of pagination?
Or else, how this would look for replacing mind_distance for created_at.
Also, for supporting both sort types, what index/es is/are needed?
One for both, or one for each?
def self.articles_with_distance(params, excluded_ids=[])
if params[:min_distance].present?
Article.collection.aggregate([
{ :"$geoNear" => {
:near => {
:type => "Point",
:coordinates => [params[:lon].to_f, params[:lat].to_f],
},
:query => {_id: { :"$nin" => excluded_ids }}, # to exclude items already shown if min distance between two pages are same
:distanceField => "distance_from",
:maxDistance => params[:radius].to_i,
:minDistance => params[:min_distance].to_i, # only need to reduce the result set by exclude items had been shown previous pages
:spherical => true,
:limit => (params[:per_page].to_i || 10)
}}
]);
else
Article.collection.aggregate([
{ :"$geoNear" => {
:near => {
:type => "Point",
:coordinates => [params[:lon].to_f, params[:lat].to_f],
},
:distanceField => "distance_from",
:maxDistance => params[:radius].to_i,
:spherical => true,
#
}},
{
:"$skip" => (params[:per_page].to_i * (params[:page].to_i-1))
},
{
:"$limit" => (params[:per_page].to_i || 10)
}
]);
end
end

Find query with and operator in PHP

Hi i am working on backend of web application & want to find the documents from mongodb database that contain key active_status with value set to both 1 & 2. With mongodb PHP i am confused of how to find with both parameters in single query.
My query was this:
$mongoDb = MongoDbConnector::getCollection("endusers");
$endUserData = $mongoDb->find(array('active_status' => 1, '$and' => array('active_status' => 2)));
I have to fetch the users whose active_status should be 1 & 2. The above query doesnt seems to work. What is the right one for that?
Thanks on advance for quick response.
You have $and the wrong way around. Both arguments need to be included:
$endUserData = $mongoDb->find(array(
'$and' => array(
array( 'active_status' => 1 )
array( 'active_status' => 2 )
)
));
And since that would only make sense when looking for both elements within an array element, then you should instead use $all, which is shorter syntax:
$endUserData = $mongoDb->find(array(
'active_status' => array( '$all' => array(1,2) )
));
I should add that unless you intend to match a document like this:
{ "active_status" => [1,2] }
The you do not in fact want $and at all, but rather you want $or or better yet $in for multiple possible values on the same field:
$endUserData = $mongoDb->find(array(
'active_status' => array( '$in' => array(1,2) )
));
This matches documents like this:
{ "active_status": 1 },
{ "active_status": 2 }

How to rename a column in a collection in Mongodb using MongoMapper?

Mongodb gives an option for renaming a column name as follows
db.collection.update({},{'$rename'=> {'old_name' => 'new_name'}}, false,true)
Is it possible for using MongoMapper to do the same? The documentation doesn't specify anything.
I also tried getting the Mongodb connection handle from MongoMapper as
connection = MongoMapper.connection
db = MongoMapper.database
collection = db.collection('collection_name')
collection .update(....)
and doing the same query but it doesn't work.
MongoMapper uses the 10gen Ruby driver, and MongoMapper::Document provides access to the underlying driver objects.
The following working test shows that you can use Model.collection.update to do what you want, to rename a field for the model 'Model'. Make sure to use the :multi => true option to update if you want to update/rename more than a single document.
app/models/model.rb
class Model
include MongoMapper::Document
end
test/unit/model_test.rb
require 'test_helper'
class ModelTest < ActiveSupport::TestCase
def setup
Model.remove
end
test "rename" do
puts "Model.collection.class: #{Model.collection.class}"
puts "Model.database.class: #{Model.database.class}"
Model.create( 'old_name' => 'name value 0', 'another_key' => 'another value 0' )
Model.create( 'old_name' => 'name value 1', 'another_key' => 'another value 1' )
assert_equal(2, Model.where( 'old_name' => { '$exists' => true } ).count)
Model.collection.update( {}, { '$rename' => { 'old_name' => 'new_name' } }, :multi => true )
assert_equal(0, Model.where( 'old_name' => { '$exists' => true } ).count)
p Model.all
end
end
$ rake test
Rack::File headers parameter replaces cache_control after Rack 1.5.
Run options:
# Running tests:
Model.collection.class: Mongo::Collection
Model.database.class: Mongo::DB
[DEPRECATED] The 'safe' write concern option has been deprecated in favor of 'w'.
[#<Model _id: BSON::ObjectId('5101809d7f11ba1256000001'), another_key: "another value 0", new_name: "name value 0">, #<Model _id: BSON::ObjectId('5101809d7f11ba1256000002'), another_key: "another value 1", new_name: "name value 1">]
.
Finished tests in 0.012344s, 81.0110 tests/s, 162.0220 assertions/s.
1 tests, 2 assertions, 0 failures, 0 errors, 0 skips

HTML-Template - Array of Hash

I have two Array of Hashes: The first contains values for a current time interval and the second contains values for a previous time interval.
#AoHcurrent=
( { node => "ABC",
link => "DEF",
time => "10:00",
value => "100",
},
{
node => "FGH",
link => "IJK",
time => "10:00",
value => "200",
},
);
#AoHprevious=
( { node => "ABC",
link => "DEF",
time => "09:45",
value => "10",
},
{ node => "FGH",
link => "IJK",
time => "09:45",
value => "50",
},
);
I want to now use HTML-Template to present this data. Something like :
NODE LINK VALUE
---------------------
ABC DEF 100(10)
FGH IJK 200 (50)
the values in brackets represent the previous value.
my %html_template_parameters =
( AOHCURRENT => \#AoHcurrent,
AOHPREVIOUS => \#AoHprevious, );
my $html_template=qq{Report.tmpl};
my $html_output=qq{Report.html};
htmlReport($html_template,$html_output,\%html_template_parameters);
where htmlReport is a function that generates the report
I require guidance on defining the Report.tmpl file.
Thanks you in advance
see also http://www.perlmonks.org/?node_id=972954
I gave an example there how this can be solved with HTML::Template::Compiled.
Basically you would navigate through the parameter stash like this:
[%= expr=".AOHPREVIOUS[__index__]{'value'}" %]
or with the classic syntax:
<TMPL_VAR expr=".AOHPREVIOUS[__index__]{'value'}" >
You can't do that with 2 separate lists just with HTML::Template. And trying to do it with HTML::Template::Expr would be a nightmare to maintain. Try collapsing them into a single list where the hash data is merged.

Why am I getting a "Odd number of elements in anonymous hash" warning in Perl?

Help, I'm trying to create a new post in my wordpress blog with custom fields using the following perl script using metaweblogAPI over XMLRPC, but there seems to be an issue with the custom fields. Only the second custom field (width) ever seems to get posted. Can't get the "height" to publish properly. When I add another field, I get the "Odd number of elements in anonymous hash" error. This has got to be something simple - would someone kindly sanity check my syntax? Thanks.
#!/usr/bin/perl -w
use strict;
use RPC::XML::Client;
use Data::Dumper;
my $cli=RPC::XML::Client->new('http://www.sitename.com/wp/xmlrpc.php');
my $appkey="perl"; # doesn't matter
my $blogid=1; # doesn't matter (except blogfarm)
my $username="Jim";
my $passwd='_____';
my $text=<<'END';
This is the post content...
You can also include html tags...
See you!
END
my $publish=0; # set to 1 to publish, 0 to put post in drafts
my $resp=$cli->send_request('metaWeblog.newPost',
$blogid,
$username,
$passwd,
{
'title' => "this is doodoo",
'description' => $text,
'custom_fields' => {
{ "key" => "height", "value" => 500 },
{ "key" => "width", "value" => 750 }
},
},
$publish);
exit 0;
While techically valid syntax, it's not doing what you think.
'custom_fields' => {
{ "key" => "height", "value" => 500 },
{ "key" => "width", "value" => 750 }
},
is roughly equivalent to something like:
'custom_fields' => {
'HASH(0x881a168)' => { "key" => "width", "value" => 750 }
},
which is certainly not what you want. (The 0x881a168 part will vary; it's actually the address where the hashref is stored.)
I'm not sure what the correct syntax for custom fields is. You can try
'custom_fields' => [
{ "key" => "height", "value" => 500 },
{ "key" => "width", "value" => 750 }
],
which will set custom_fields to an array of hashes. But that may not be right. It depends on what send_request expects.