[wp-trac] [WordPress Trac] #34848: Add support for updating post meta in bulk
WordPress Trac
noreply at wordpress.org
Fri Dec 4 19:43:49 UTC 2015
#34848: Add support for updating post meta in bulk
--------------------------------+-----------------------------
Reporter: patrickgarman | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Options, Meta APIs | Version:
Severity: normal | Keywords:
Focuses: |
--------------------------------+-----------------------------
A limiting factor in performance of inserting posts into the database is
postmeta. I've been running a patch locally which adds functions for
adding postmeta in one function call instead of calling add_post_meta
multiple times over and over.
add_post_meta creates a single SQL insert query, when adding 20 post metas
that is 20 SQL inserts all run separately. This can be greatly improved by
combining these into a single SQL insert.
There is a problem where updating meta in bulk would likely be impossible
or very painful. At the very least I have not been able to find a way to
do this. Deleting I haven't developed a function but I imagine it would be
fairly easy.
{{{#!php
/**
* Add metadatas to a post.
*
* @since x.x.x
*
* @param int $post_id Post ID.
* @param string $meta_data Metadata as an key/value pair array
*
* @return bool Was the data inserted
*/
function add_post_metas( $post_id, $meta_data ) {
// Make sure meta is added to the post, not a revision.
if ( $the_post = wp_is_post_revision($post_id) )
$post_id = $the_post;
return add_metadatas('post', $post_id, $meta_data);
}
/**
* Add multiple metadatas for the specified object. Similar to calling
add_metadata for each metadata individually,
* and is only applicable for unique meta data. If a meta key already
exists for an object it will not be stored.
*
* @since x.x.x
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param string $meta_type Type of object metadata is for (e.g.,
comment, post, or user)
* @param int $object_id ID of the object metadata is for
* @param array $meta_data Metadata as an key/value pair array
*
* @return bool If the metadata was stored successfully.
*/
function add_metadatas($meta_type, $object_id, $meta_data) {
global $wpdb;
if ( ! $meta_type || ! is_array( $meta_data ) || ! is_numeric(
$object_id ) ) {
return false;
}
$object_id = absint( $object_id );
if ( ! $object_id ) {
return false;
}
$table = _get_meta_table( $meta_type );
if ( ! $table ) {
return false;
}
$column = sanitize_key($meta_type . '_id');
/**
* Filter whether to add metadatas of a specific type.
*
* The dynamic portion of the hook, `$meta_type`, refers to the
meta
* object type (comment, post, or user). Returning a non-null
value
* will effectively short-circuit the function.
*
* @since x.x.x
*
* @param null|bool $check Whether to allow adding metadata
for the given type.
* @param int $object_id Object ID.
* @param string $meta_key Meta key.
* @param mixed $meta_value Meta value. Must be serializable
if non-scalar.
* @param bool $unique Whether the specified meta key
should be unique
* for the object. Optional. Default
false.
*/
$check = apply_filters( "add_{$meta_type}_metadatas", null,
$object_id, $meta_data );
if ( null !== $check )
return $check;
$_meta_data = array();
foreach( $meta_data as $key => $value ) {
if ( 0 == absint( $wpdb->get_var(
$wpdb->prepare( "SELECT COUNT(*) FROM
$table WHERE meta_key = %s AND $column = %d", $key, $object_id )
) ) ) {
$key = wp_unslash( $key );
$value = wp_unslash( sanitize_meta( $key, $value,
$meta_type ) );
$_meta_data[ $key ] = maybe_serialize( $value );
/**
* Fires immediately before meta of a specific
type is added.
*
* The dynamic portion of the hook, `$meta_type`,
refers to the meta
* object type (comment, post, or user).
*
* @since 3.1.0
*
* @param int $object_id Object ID.
* @param string $meta_key Meta key.
* @param mixed $meta_value Meta value.
*/
do_action( "add_{$meta_type}_meta", $object_id,
$key, $value );
}
}
$rows = array();
if( ! empty( $_meta_data ) ) {
$sql = "INSERT INTO {$table} ({$column}, meta_key,
meta_value) VALUES ";
$comma = false;
foreach( $_meta_data as $key => $value ) {
if( true == $comma ) {
$sql .= ',';
}
$sql .= "({$object_id}, '{$key}', '{$value}')";
$comma = true;
}
}
$result = $wpdb->query( $sql );
if ( ! $result )
return false;
wp_cache_delete($object_id, $meta_type . '_meta');
return true;
}
}}}
--
Ticket URL: <https://core.trac.wordpress.org/ticket/34848>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list