I'm running the following query to the lookback API to find stories in a date range that were unblocked, but I'm getting no results. Am I missing something obvious? No errors, warnings or results returned.
Below is the Generated Query I get back from the lookback API:
'GeneratedQuery' => {
'fields' => 'true',
'skip' => 0,
'limit' => 100,
'find' => {
'_PreviousValues.Blocked' => 'true',
'_TypeHierarchy' => -51038,
'Blocked' => 'false',
'_ValidFrom' => {
'$lte' => '2012-11-02T04:00:00.000Z',
'$gte' => '2012-07-01T04:00:00.000Z'
}
}
},
When you pass in Boolean values, you need to make sure that they are bare true or false. If you pass them in as Strings, it will not behave as expected. Similarly for values of type Number. They should not have quotes around them.
Ok, the problem was related to "true" and "false" and the fact that I'm using Perl.
I'm using the Perl JSON library, and I didn't realize that you need to pass in JSON::true() and JSON::false() for true and false, not the literals 'true' and 'false'. So, in effect Larry was right: it was passing "true" instead of true.
Related
I have a form which has date_of_purchasing and expiry_date. I need to check date_of_purchasing should not be greater than expiry_date. How can i write this validation rule in model.
Im using YII framework. And im new for this framework.
Yii2
This should work if the compared column comes from the same table.
public function rules()
{
return [
[
['date_end'],
'compare',
'compareAttribute' => 'date_start',
'operator' => '>=',
'type' => yii\validators\DateValidator::TYPE_DATE,
'message' => 'Date end has to be greater than date start',
'enableClientValidation' => false
],
// other rules...
];
}
Don't forget to set enableClientValidation to false because Yii2 can't check the other date without a server side request.
Other configuration options here.
PS. I decided to update this thread 3+ years after because it remains
one of the first StackOverflow results on Google Search for this argoument.
Try to use CompareValidator at this link: Compare .
I have this silverstripe query that does not work ( it outputs all messages and not the ones with the date range )
What would be the best way to tackle this query?
Im fairly new to silverstripe and havent been able to find information on how to print the raw query.
return = Message::get()
->filter(array(
'IsPublished' => true,
'StartPublication:LessThanOrEqual' => date('Y-m-d'),
'Priority' => array('High', 'Normal')
))
->where("\"StopPublication\" >= ".date('Y-m-d')." OR \"StopPublication\" IS NULL")
->sort('StartPublication', 'DESC')->limit($this->getLimit());
The correct answer is to not use where() - this is a trap method that a lot of learners fall into (presumably due to the name). It's intended basically only for very complex things that the ORM just can't handle.
You're calling filter at least, which is the correct thing. But what you want instead of where() is filterAny():
Message::get()
->filter([
'IsPublished' => true,
'StartPublication:LessThanOrEqual' => 'now',
'Priority' => ['High', 'Normal']
])
->filterAny([
'StopPublication:GreaterThanOrEqual' => 'now',
'StopPublication' => null
])
->sort('StartPublication', 'DESC')
->limit($this->getLimit());
As the other answer already specifies, do not use an = on the return (or put a $ in front of return to make it a variable), and to return the query itself use $datalist->sql() http://api.silverstripe.org/3.1/class-DataList.html#_sql
But - seeing the docs on SQLQuery is wrong, because you're not using SQLQuery. You're using the ORM, so this doc page is far more relevant: http://docs.silverstripe.org/en/3.1/developer_guides/model/data_model_and_orm/#filterany
For starts return = Message::get() its just return Message::get()
I assume that you have set php error reporting so that it outputs errors and SS is also in development mode so it won't hide error outputs.
The answer to your question is to to do either:
to output it to the output html:
Debug::dump(Message::get()
->filter(array(
'IsPublished' => true,
'StartPublication:LessThanOrEqual' => date('Y-m-d'),
'Priority' => array('High', 'Normal')
))
->where("\"StopPublication\" >= ".date('Y-m-d')." OR \"StopPublication\" IS NULL")
->sort('StartPublication', 'DESC')->limit($this->getLimit())->sql());
or output it to the project roots log file
Debug::log(Message::get()
->filter(array(
'IsPublished' => true,
'StartPublication:LessThanOrEqual' => date('Y-m-d'),
'Priority' => array('High', 'Normal')
))
->where("\"StopPublication\" >= ".date('Y-m-d')." OR \"StopPublication\" IS NULL")
->sort('StartPublication', 'DESC')->limit($this->getLimit())->sql());
See http://docs.silverstripe.org/en/developer_guides/model/sql_query/
I'm trying to subscribe a single email to multiple lists with RoR and the official mailchimp-api gem. It works, but the last four values (double_optin, update_existing, replace_interests, and send_welcome) are not updating and I get an error that the email "already exists" even though I'm trying to pass the update_existing as true. I've written Mailchimp several times and they feel they've reached the end of their assistance. They have said they are not experts in the wrapper--even if it is the "official" gem--and cannot help me further. My code looks like this:
responses << mailchimp_lists.each do |ml|
mailchimp.lists.subscribe(
ml,
{ "email" => order.customer_email,
"euid" => order.customer_id,
"leid" => ""
},
{ "FNAME" => order.customer_first_name,
"LNAME" => order.customer_last_name,
"COMPANY" => order.company_name,
"ADDRESS1" => order.billing_address_1,
"ADDRESS2" => order.billing_address_2,
"CITY" => order.billing_city,
"STATE" => order.billing_state,
"POSTALCODE" => order.billing_zip,
"SALUTATION" => ""
},
"html",
false,
true,
false,
false
)
end
I've tried sending the last four params in several different ways such as:
"email_type" => "html",
"double_optin" => false,
Or:
{"email_type" => "html"},
{"double_optin" => false}
At times, Mailchimp can see the params arrive in such a way that it seems it should not be triggering an "email already exists" error, but it just won't work. Any help is appreciated.
The mailchimp-api gem's documentation describes the subscribe method as:
#subscribe(id, email, merge_vars = nil, email_type = 'html', double_optin = true, update_existing = false, replace_interests = true, send_welcome = false)
While the batch_subscribe shows:
#batch_subscribe(id, batch, double_optin = true, update_existing = false, replace_interests = true)
Note that the batch method does not include a "send_welcome" param. When I removed it from my list of params for the subscribe method--essentially sending three booleans instead of four as suggested, the update_existing worked perfectly. Seems like an error in the documentation here: http://www.rubydoc.info/gems/mailchimp-api/2.0.4/Mailchimp/Lists#subscribe-instance_method
Hopefully this helps someone else!
In SQL, I can search email addresses pretty well with SQL LIKE.
With an email "stack#domain.com", searching "stack", "#domain.com", "domain.com", or "domain" would get me back the desired email address.
How can I get the same result with ElasticSearch?
I played with nGram, edgeNGram, uax_url_email, etc and the search results have been pretty bad. Please correct me if I'm wrong, it sounds like I have to do the following:
for index_analyzer
use "keyword", "whitespace", or "uax_url_email" tokenizer so the email don't get tokenized
but wildcard queries don't seem to work (with tire at least)
use "nGram" or "edgeNGram" for filter
I always get way too many unwanted results like getting "first#domain.com" when searching "first-second".
for search_analyzer
don't do nGram
One experiment code
tire.settings :number_of_shards => 1,
:number_of_replicas => 1,
:analysis => {
:filter => {
:db_ngram => {
"type" => "nGram",
"max_gram" => 255,
"min_gram" => 3 }
},
:analyzer => {
:string_analyzer => {
"tokenizer" => "standard",
"filter" => ["standard", "lowercase", "asciifolding", "db_ngram"],
"type" => "custom" },
:index_name_analyzer => {
"tokenizer" => "standard",
"filter" => ["standard", "lowercase", "asciifolding"],
"type" => "custom" },
:search_name_analyzer => {
"tokenizer" => "whitespace",
"filter" => ["lowercase", "db_ngram"],
"type" => "custom" },
:index_email_analyzer => {
"tokenizer" => "whitespace",
"filter" => ["lowercase"],
"type" => "custom" }
}
} do
mapping do
indexes :id, :index => :not_analyzed
indexes :name, :index_analyzer => 'index_name_analyzer', :search_analyzer => 'search_name_analyzer'
indexes :email, :index_analyzer => 'index_email_analyzer', :search_analyzer => 'search_email_analyzer'
end
end
Specific cases that don't work well:
emails with hyphen (eg. email-hyphen#domain.com)
query string '#' at the beginning or end
exact matches
searching with wildcard like '#' gets very unexpected results.
Suppose I have, "aaa#email.com", "aaa_0#email.com", and "aaa-0#email.com, searching "aaa" gives me "aaa#a.com" "aaa-0#email.com. Searching "aaa*" give me everything, but "aaa-*" gives me nothing. So, how should I do exact match wildcard queries? For these type of queries, I get pretty much the same results for different tokenizer/analyzer.
I do these after each mapping change:
Model.tire.index.delete
Model.tire.create_elasticsearch_index
Model.tire.index.import Model.all
References:
Configure ElasticSearch to use ngram by default. - SQL LIKE %% behavior
http://euphonious-intuition.com/2012/08/more-complicated-mapping-in-elasticsearch/
Considering what you are trying to accomplish, KeywordAnalyzer might be a reasonable choice of analyzer, though I don't see anything that would cause problems with a WhitespaceAnalyzer.
I suspect you are running into problems with the query parsing and analysis, although you haven't really described how you are querying. Simplest case would be to simply use term or prefix queries.
It does seem a bit like StandardAnalyzer would serve your purpose here, mostly (differentiating between "aaa_0" and "aaa-0" would be a problem), as long as it is applied consistently, and your query is correct.
I'm doing a mutli-index query With Tire and rails 3 and I want to filter out Venues who have approved => false so I need some sort of combo filter.
Here is the query
query = params[:q]
from = params.delete(:from)
size = params[:size] || 25
Tire.search(
[Venue.index_name,
Performer.index_name, User.index_name], load: true) do |s|
s.query do
string(query, fields: [:_all, :name, :title], use_dis_max: true)
end
s.from from if from
s.size size if size
end.results.to_a
This line removes all Performers and Users because they don't have an :approved field.
s.filter(:term, :approved => true )
And this line obviously removes all non-venues which is no good.
s.filter(:term, { :approved => true, :index_name => 'venues'} )
Any ideas besides adding an approved: true field to all Users and Performers? I think something like this is what I want conceptually:
s.filter(:term, :approved => true, :if => {:index_name => 'venues'} )
EDIT Thanks to Mallox I was able to find the Should construct but I'm still struggling to implement it Tire. It seems like the below code should work but it return no results on any query. I also remove the "{:terms => { :index_name => ["performers", "users"]}}," to make sure it wasn't my use of index name or multiple lines of query that was the problem and still no luck. Can anybody shed some light on how to do this in Tire?
s.filter(:bool, :should => [
{:terms => { :index_name => ["performers", "users"]}},
{:term => { :approved => true}},
] )
So i have little knowledge about Ruby and Tire, but the ElasticSearch query that you want to build would be based on a bool filter, that contains some "should" entries (which would translate into inclusive OR).
So in your case something along the lines of:
"filter" : {
"bool" : {
"should" : [
{
"terms" : { "_type" : ["Performers","Users"] }
},
{
"term" : { "approved" : true }
}
]
}
}
Take a look at the documentation here, maybe that'll help:
:http://www.elasticsearch.org/guide/reference/query-dsl/bool-filter/