Elasticsearch / Elasticpress find ALL terms - wordpress

I've been struggling to make my search work as expected, mainly because I don't know what kind of query I should make to fullfill my needs.
Essentially, what I am looking for, is that the results ideally would only include posts that include every term, but also keep fuzziness applied.
For example, if I look for the term '215 tires' it should bring results like:
215 tires
217 tires
225 tires
215 tire
...
I am in the process of creating an app and have been learning too many stuff, and Elasticsearch is just a part of it, but it is HUGE. I've done some testing but looks like I am missing something.
Based on my understanding, I would expect something like the following query to work:
$query = array(
'bool' => array(
'should' => array(
array(
'multi_match' => array(
'query' => '',
'fields' => $search_fields,
'boost' => apply_filters( 'ep_match_boost', 2, $search_fields, $args ),
'fuzziness' => 1,
'operator' => 'and',
),
),
);
Obviously I am doing something wrong, because I am not getting the results I am expecting, eg if I search '215 tires' I am getting results also for '215' alone, without any mention of the word 'tires'.
I experimented a lot by the most famous trial and error technique but it bear no fruit. Any help?

I am relatively new to ES, but from the look of you question you want probably want to look at termsbut terms cannot be used with text datatypes as analyzers can sometime change words if you want a solution that is more robust then have a look at score by word position, here is a question that was asked, I think it might solve your problem.

Related

How can I force a WordPress Query to satisfy ALL requirements?

I have 2 categories, called red and blue.
I have 2 posts, called red-post and blue-post. These posts are of their corresponding categories.
If I create the following query:
$bluePostQuery = new WP_Query(array('category' => 'red', 'name' => 'blue-post'));
This query will return blue-post, even though my query has category=red as a requirement. Why does this happen? blue-post is of the category blue, not red, so I want nothing returned here. Will a query always return if the name argument is provided, even if the other arguments are not met?
It may be ignoring 'category' because that is not a valid parameter for finding a category in WP Query. Here's a list of the valid params for cats. You might try using the category name parameter, like so:
$bluePostQuery = new WP_Query(
array(
'category_name' => 'red',
'name' => 'blue-post'
)
);
Alternatively, if you are searcing for a specific post, and know its slug, the category doesn't really matter, so you could just exclude it.

bbpress user-roles or capabilities per forum

I'm trying to setup a bbpress with extended user capabilities.
The problem
My goal is that users need to have different capabilities in each forum, i.e:
UserA can't access ForumW
UserA can only read topics and replies in ForumX
UserA can create topics and write replies in ForumY
UserA can moderate ForumZ
Plugins
These are the plugins I tried so far, but without success:
Ultimate Member, official 1.7 and the new 2.0 version
https://ultimatemember.com/
They claim that they're working on a groups extension for UltimateMember v2, which somehow looks promising, but as of now there's no release date and I still don't know if this extension is going to solve my problem.
itthinx Groups plugin
http://docs.itthinx.com/document/groups/
Allows me to assign multiple groups to users and forums, but there's still a catch.
First attempt
Since itthinx Groups plugin allows me to assign multiple groups to UserA, which is great, it's still not solving my issue.
So, I tried something like this:
ForumX has the following groups assigned: ForumX_readers, ForumX_writers, ForumX_moderators
UserA has the following groups assigned: ForumX_readers, ForumY_writers, ForumZ_moderators
But the problem is, since UserA belongs to groups that have publish_replies and moderate capabilities, he has full access to ForumX.
So what I need is an intersection of the forum-groups and the user-groups - which in this example is ForumX_readers.
The promising part, but...
I digged into the code of the plugin and found the line that handles the capabilities of the user based on his assigned groups and quickly tried to get the current forum groups, to implement the intersection.
Unfortunatelly I was not able to access the global $post, the $_GLOBALS['post'] nor the $_REQUEST[] variables in this part of code. Neither directly nor with an apply_filters() function, that I implemented into the part of the code myself.
UPDATE:
I was able to get the ID with get_posts() and the slug of the current forum/topic.
So, my question
Is there any solution to my first attempt, which I may have overseen?
If not, is there maybe any other plugin that can solve my problem that I'm not aware of?
Or is something like that even impossible in bbpress?
After some further research and trial & error, I finally figured it out.
First step to do is to set up the capabilities, which in my case look something like this.
In the plugins directory, there is the file core/class-groups-user.php. The init_cache() function retrieves the assigned groups to the user, and sets the according capabilities.
To not mess around to much with the core-plugin, I applied a filter to the $group_ids variable which can be found in line: 415.
foreach( $user_groups as $user_group ) {
$group_ids[] = Groups_Utility::id( $user_group->group_id );
}
// added this line
$group_ids = apply_filters('filter_user_group_ids', $group_ids);`
I then created a new plugin, which hooks into this filter.
add_filter('filter_user_group_ids', 'dnmc_filter_groups', 10, 1);
function dnmc_filter_groups($user_group_ids) {
$forum_id = dnmc_get_forum_id();
if(!$forum_id) return $user_group_ids;
$forum_group_ids = Groups_Post_Access::get_read_group_ids( $forum_id);
$user_restricted_forum_group_ids = array_intersect($user_group_ids, $forum_group_ids);
return $user_restricted_forum_group_ids;
}
function dnmc_get_forum_id() {
$args_topic = array(
'name' => basename( untrailingslashit( rtrim($_SERVER['REQUEST_URI'], '/') ) ),
'post_type' => 'topic',
'post_status' => 'publish',
'numberposts' => 1
);
if($topic = get_posts($args_topic)) {
return $topic[0]->post_parent;
}
$args_forum = array(
'name' => basename( untrailingslashit( rtrim($_SERVER['REQUEST_URI'], '/') ) ),
'post_type' => 'forum',
'post_status' => 'publish',
'numberposts' => 1
);
if($forum = get_posts($args_forum)) {
return $forum[0]->ID;
}
return false;
}

Sort and paginate by custom date field with Wordpress / ACF / Timber

I'll try to describe what it is I want to achieve, please let me know if too much/not enough detail!
I'm making a site that needs to have documents uploaded to it. These documents will belong to one only of four categories and there will be one page per category. On this page, by default all documents will display. Users will also be able to view only the documents from each year by clicking a link.
It also needs to have pagination so a max of 10 documents are displayed per page.
So how I would ideally like to do this is to make a custom post type (documents) which would then display an ACF custom field set. The field set would have three fields (doc_type, doc_file and release_date). doc_type would be a select field of the four categories, doc_file a file upload and release_date a datepicker field.
When you click on a page, the controller would select by doc_type to only show the documents that belong to that category.
I want to order by release_date and use the year from this field as the display text of my links. For the actual href, I'm imagining something like /path/to/page.php?year=2017.
So there's a few problems here: first is that I am not sure if what I want to do is even possible - let alone a good way of doing things - with WordPress. I'm more used to pure PHP and mySQL, and so I might be trying to shoehorn more general solutions into WP. Can anyone confirm if it's possible to achieve what I want?
Second, I'm specifically running into some issues when I try to execute this plan.
I can successfully get each page to only display the documents that belong to it, like so (although I'm generating $last by grabbing info from the URI, which seems dodgy).
$docArgs = array(
'post_type' => 'documents',
'meta_key' => 'doc_type',
'meta_value' => $last,
);
$context['documents'] = Timber::get_posts($docArgs);
When I try to get my sorting on though, de nada:
$docArgs = array(
'post_type' => 'documents',
'meta_key' => 'doc_type',
'meta_value' => $last,
'meta_query' => array(
array(
'key' => 'release_date',
'orderby' => 'meta_value_num',
'order' => DESC,
),
),
);
I assume I've got the syntax wrong, but I'm basically really confused about the whole thing. Any suggestions?

Lucene.Net.Search.BooleanQuery+TooManyClauses: System error

I am trying to search with the below params, and I am wondering why some cause this exception to be thrown.
Only a few params are not working. All others are working.
?q=220v+0+ph => Not working
?q=220v+1+ph => Not working
?q=220v+2+ph => Not working
?q=220v+3+ph => Not working
?q=220v+4+ph => Working
?q=220v+5+ph => Working
?q=220v+6+ph => Working
?q=220v+7+ph => Working
?q=220v+8+ph => Working
?q=220v+9+ph => Working
I am checking the center character. It is not working only in the cases of 0, 1, 2 and 3.
Query: {+(title:480v* content:480v title:3* content:3 title:ph* content:ph)
One or more of your wildcard queries is generating too many term matches. Wildcard queries are rewritten by enumerating all of the matching terms, and create a set of primitive queries matching them, combined in a BooleanQuery.
For instance, the query title:foo*, could be rewritten to title:foobar title:food title:foolish title:footpad, in an index containing those terms.
By default, a BooleanQuery allows a maximum of 1024 clauses. If you have over 1024 different terms in the index matching title:0*, for instance, that is likely your problem.

Drupal form validation functions

Is there anyway say Drupal to validate form elements like email fields, passwords, numeric fields validate automatically lets say bind a system validator
$form['email] = array(
'#title' => t('Email'),
'#type' => 'textfield',
'#validate_as' => array('email', ...),
...
);
To validate a numeric field in Drupal use:
'#element_validate' => array('element_validate_number')
No need to create a custom validation function.
http://api.drupal.org/api/drupal/includes%21form.inc/function/element_validate_number/7
Rimian is both correct and wrong.
The good thing as Rimian points out, is that you can attach any validation function to your form fields using the #element_validate.
However I'm not aware of a set of form api validation functions you can call to test most common things like, if the value is:
a int
a positive int
a valid date (such a function exists in the date module though)
a email-address (you can use valid_email_address to check the email, but you need a function to raise validation error)
So while you can do this, it's a bit more work than you were hoping for, as you will need to create these validation functions yourself. But once you have done this, you can reuse them with #element_validate.
The use of #element_validate is mostly centered around complex validation fx date validation, location validation and such, as it requires some work to create these validation functions. Most of the time, you don't need to validate that many numbers etc (which you quite easily could do within a normal validation function using a loop). So I'm not sure how much this will be of help to you, but it's definitely a possibility.
The Form API Validation module does exactly what you request: http://drupal.org/project/fapi_validation
For client-side validation there is also http://drupal.org/project/clientside_validation (which can use rules provided by Form API Validation).
Yep!
Though I have not experimented with it much.
http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/6#element_validate
$form = array(
'#type' => 'fieldset',
'#title' => t('Input format'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => $weight,
'#element_validate' => array('filter_form_validate'),
);

Resources