New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to return related posts for French content #1077

Closed
janvitos opened this Issue May 8, 2018 · 11 comments

Comments

Projects
None yet
5 participants
@janvitos
Contributor

janvitos commented May 8, 2018

Hi,

I've been struggling to return related posts on my site. I've used the code in the related posts widget as an example to make my own related posts function. Though, I cannot get related posts to be returned. Instead, recent posts on my site are returned and are mostly unrelated to the main post.

Here is my related posts function:

<?php
	if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
	function popular_posts() {
?>
<div id="latest-posts">
	<div class="tendance-title">Articles connexes</div>
	<div class="latest-posts">
		<?php
			$recent_posts = ep_find_related( get_the_ID(), 10 );
			ob_start();
			foreach((array) $recent_posts as $recent ){ ?>
				<!-- Post -->
				<div class="small-thumb-post">
					<div class="cont-img">
						<a href="<?php echo esc_url( get_permalink( $recent->ID ) ); ?>"><?php echo get_the_post_thumbnail( $recent->ID, 'thumbnail' ); ?></a>
						<div class="description">
							<h2><a href="<?php echo esc_url( get_permalink( $recent->ID ) ); ?>"><?php echo esc_html( get_the_title( $recent->ID ) ); ?></a></h2>
						</div>
					</div>
				</div>
			<?php }
			wp_reset_postdata();
			$recent_posts = ob_get_clean();
			echo $recent_posts;
		?>
	</div>
</div>
<?php } ?>

I'm thinking this might have something to do with the fact that my site is in French, so I've been trying to get the French analyzer working with related posts. After installing the ICU Analysis Plugin and restarting the Elasticsearch service, I've created the following code that I placed in my theme's functions.php :

function set_related_posts_fields( $fields ) {
	$fields = array( 'post_title', 'post_content', 'terms.post_tag.name' );
	return $fields;
}
add_filter('ep_related_posts_fields', 'set_related_posts_fields', 10, 1);

function elasticpress_config_mapping( $mapping ) {

	$mapping['settings']['analysis']['filter']['french_elision'] = array(
		'type' => 'elision',
		'articles_case' => true,
		'articles' => array(
			'l', 'm', 't', 'qu', 'n', 's', 'j', 'd', 'c', 'jusqu', 'quoiqu', 'lorsqu', 'puisqu',
		),
	);
	$mapping['settings']['analysis']['filter']['french_stop'] = array(
		'type' => 'stop',
		'stopwords' => '_french_',
	);
	$mapping['settings']['analysis']['filter']['french_stemmer'] = array(
		'type' => 'stemmer',
		'language' => 'light_french',
	);

	$mapping['settings']['analysis']['analyzer']['french']['tokenizer'] = 'icu_tokenizer';
	$mapping['settings']['analysis']['analyzer']['french']['filter'] = array( 'french_elision', 'french_stop', 'icu_folding' );

	$mapping['mappings']['post']['properties']['post_title']['analyzer'] = 'french';
	$mapping['mappings']['post']['properties']['post_content']['analyzer'] = 'french';

	return $mapping;
}

add_filter( 'ep_config_mapping', 'elasticpress_config_mapping', 10, 1 );

Although I'm pretty sure this code is correct, I'm still not getting any related posts to show up. After reindexing my site with ElasticPress, only the recent posts show up like before. The only way I was able to get some related results was by using only the post_title field, and not post_content or terms.post_tag.name. I also tried reindexing with only the post_content analyzer mapping, but the same problem occurs and only recent posts are shown.

If anyone can provide any type of advice, that would be great.

I'll happily provide more details should someone request them.

Thank you.

@allan23

This comment has been minimized.

Collaborator

allan23 commented May 8, 2018

Hi @janvitos,
I ran an experiment on my development environment and found that ep_find_related() is failing and actually falling back to a normal WP_Query which returns recent posts.

I am going to dig deeper to find the root cause of why this is happening.

@janvitos

This comment has been minimized.

Contributor

janvitos commented May 8, 2018

Alrighty @allan23. Good to know here's a real issue and I'm not just crazy.

If I can do anything to help, I'll be glad to assist.

Thank you.

P.S. I forgot to mention I'm using ElasticSearch 5.6.9. I tried using 6.2.4 but it wasn't working at all.

@janvitos

This comment has been minimized.

Contributor

janvitos commented May 9, 2018

Hi again @allan23. So I did a bit of research / testing on my end and ended up with pretty nice results.

Here's what I stumbled on after installing the Debug Bar & Debug Bar ElasticPress plugins for Wordpress and looking at the different Queries.

While looking at the Query Result, I noticed that the "max_score" and "_score" were always "null". While searching on the web, I found out that when a Query is sorted, it needs to have "track_scores" set to true for the scores to be computed. After looking at the Query Body, I found out that the query was indeed being sorted by "post_date". I tried passing "track_scores" to the query, but although I was now getting some scores, the posts remained the same because they were still sorted by date, and not by relevance.

What I did was edit the class-ep-api.php file to change the default sort order from "date" to "_score", and just like magic, related results were now being returned properly, even better than I could have imagined.

What I would suggest is to have the related post sorted by relevance (score) AND by date, if that's possible, by passing "track_scores" to the query to make verything work. If not, then sorting by relevance only is probably more than enough.

I hope my findings will help.

I really love this plugin as it is adding a whole bunch of great features to my site, and I'll be really happy if my findings can help other people too.

Thank you.

@janvitos

This comment has been minimized.

Contributor

janvitos commented May 9, 2018

So here's what I've come up with to fix the issue.

Replace this code in class-ep-api.php

// Default sort for non-searches to date
if ( empty( $args['orderby'] ) && ( ! isset( $args['s'] ) || '' === $args['s'] ) ) {
	$args['orderby'] = 'date';
}

With this code

// Default sort for non-searches to date
if ( empty( $args['orderby'] ) && ( ! isset( $args['s'] ) || '' === $args['s'] ) ) {
	$args['orderby'] = apply_filters( 'ep_set_default_sort', 'date', $order );
}

That way, the default sort is still by date, but people can change it to "_score" using the ep_set_default_sort filter if they wish to.

But maybe it would still be a good idea to have the more like this query results sorted by score AND by date... you tell me !

@tlovett1 tlovett1 added the question label May 9, 2018

@allan23

This comment has been minimized.

Collaborator

allan23 commented May 15, 2018

Nice work @janvitos. I'll plug in your code and run some further tests.

@janvitos

This comment has been minimized.

Contributor

janvitos commented May 21, 2018

Awesome @allan23. I've been using this code on my site for a few days and related posts are really meaningful now.

@janiosarmento

This comment has been minimized.

janiosarmento commented Jun 8, 2018

Hello,

My sites are in Portuguese, and there is no way I can use the related posts. The widget always returns my most recent posts, and the ep_find_related function does not return a valid WP_Query object. :(

@allan23

This comment has been minimized.

Collaborator

allan23 commented Jun 11, 2018

@janvitos would you like to submit a pull request with your code?

@janvitos

This comment has been minimized.

Contributor

janvitos commented Jun 27, 2018

@allan23, sorry for the late reply. I could certainly do so.

@janvitos

This comment has been minimized.

Contributor

janvitos commented Jun 27, 2018

#1103 pull request added.

@brandwaffle brandwaffle added this to the 2.6 milestone Aug 2, 2018

@allan23

This comment has been minimized.

Collaborator

allan23 commented Aug 21, 2018

Thank you @janvitos!

@allan23 allan23 closed this Aug 21, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment