QUESTION: How to search in custom data?
Describe your question
Hi there,
I successfully achieved to add additional data to the search index by modifying Post.php and mappings/post/*.php.
However it is still not possible to search in that data. What is the necessary step to retrieve search results?
Thanks
Hi @btxtiger ,
As we don't know what changes you did to post.php and the mapping file (something we highly not recommend), we'd not be able to help out much. Can you describe in details what changes you did, what data are your looking to search, etc?
Thanks!
@oscarssanchez Added to post.php:
public function prepare_document($post_id) {
// ...
$post_args = array(
'wc_product' => $this->prepare_wc_data($post_id),
// ...
)
// ...
}
// ...
public function prepare_wc_data($post_id)
{
$product = wc_get_product($post_id);
if (!($product)) {
return [];
}
return [
'price' => $product->get_price(),
'salePrice' => $product->get_sale_price(),
'regularPrice' => $product->get_regular_price(),
'sku' => $product->get_sku(),
'stockStatus' => $product->get_stock_status(),
'stockQuantity' => $product->get_stock_quantity(),
'avgRating' => $product->get_average_rating()
];
}
What I added in mapping:
'wc_product' => array(
'type' => 'object',
'properties' => array(
'price' => array(
'type' => 'text',
),
'salePrice' => array(
'type' => 'text',
),
'regularPrice' => array(
'type' => 'text',
),
'sku' => array(
'type' => 'text',
),
'stockStatus' => array(
'type' => 'text',
),
'stockQuantity' => array(
'type' => 'integer',
),
'avgRating' => array(
'type' => 'text',
)
)
),
However I did not understand what the mapping is used for, just tried to reverse engineer how the index was created. The data appears now in the index, but is not searchable. Thanks for help
@oscarssanchez basically I want to be able to find the value that I've added as property "sku". How can I search it?
Hi @btxtiger,
Most of WooCommerce products info is already indexed when you have the WooCommerce feature enabled in the ElasticPress dashboard (wp-admin/admin.php?page=elasticpress)
To @oscarssanchez's point, we do not recommend editing the plugin code. Instead, you could use the ep_post_sync_args_post_prepare_meta filter to change the post (in this case product) before it is sent to Elasticsearch (see here.)
Although not a 1:1 comparison, you can think of mapping as a database table schema. It contains information about each field and how Elasticsearch will store and search on it. If you ever need to change the mapping, you can use the ep_post_mapping filter (see here.)
All that said, in the case you have at hand I'd recommend you:
- Check what the WooCommerce EP feature already indexes and what you need that is not indexed yet
- Instead of adding new fields to the mapping, you could use the
ep_prepare_meta_datafilter to create new "virtual" meta fields, that would only exist in Elasticsearch - You can add the field to be searchable using what is outlined in this blog post or, if you are in a multisite, using the search_fields parameter in WP_Query (you cans set that using WordPress pre_get_posts action)
Some considerations:
- SKUs are already searchable by default, you should not have to code anything to have that searched
- WooCommerce has some logic to calculate prices, dates being a factor in that logic (Product X costs Y but only until tomorrow.) The content indexed in Elasticsearch is "static" and will not be updated based on a date. You will have to reindex the product again to update its price.
Hi @felipeelia , thanks for the detailed reply. However I wanted to let you know, that this didn't help me in any way regarding my question as I am developing a custom fork of the plugin, and my intention was to search in any custom data – just this WC fields as example here, so the WC EP feature ist not an option, and I decide about the sources of the additional data by myself. The step that I wanted to skip, was creating the Elastic index and search API from scratch, when I just could search in any custom data objects when using this Plugin. So I'm continuing understanding the plugin code and share my results if I was able to override the default behaviour. Best regards