Wie frage ich nach Beiträgen nach teilweisem Metaschlüssel?

Ich habe eine function, die den “Like” Status für einen Beitrag als Post-Meta speichert. Ich möchte das “Gefällt mir” dem Benutzer zuordnen, der es gemocht hat, also habe ich ein benutzerdefiniertes Feld namens “like_status_ {user_id}” eingerichtet (wobei {user_id} die ID des aktuell angemeldeten Benutzers ist), die ich als 0 oder speichern kann 1. Für einen Post mit mehreren “Likes” gäbe es mehrere Meta-Werte in der db, die folgendermaßen aussehen:

'meta_key' = 'like_status_0' 'meta_value' = 1 'meta_key' = 'like_status_2' 'meta_value' = 1 'meta_key' = 'like_status_34' 'meta_value' = 1 

….und so weiter.

Es gibt potenziell Tausende von Likes für einen bestimmten Beitrag. Wie würde ich eine Abfrage ausführen, die anzeigt, ob jemand anderen diesen Beitrag auch gefallen hat?

Ich dachte etwa so:

 $query = new WP_Query(array( 'meta_key' => 'like_status_{user_id}', 'meta_value' => 1, )); 

Ich versuche, eine Benachrichtigung an alle zu schicken, die einen Beitrag gemocht haben, wenn jemand anderen diesen Beitrag mag … etwas wie “Hey, jemand anders hat diesen Beitrag gemocht, den du magst. Du solltest es ausprobieren!” Aber ich brauche einen Weg, um herauszufinden, ob jemand anderen diesen Beitrag gemocht hat und wenn ja, wer sie sein würden, damit ich sie benachrichtigen könnte.

Wenn es nicht möglich ist, könnten Sie eine bessere Möglichkeit vorschlagen, diese Daten als post_meta zu speichern und gleichzeitig die Effizienz der schnellen Aktualisierung des Status eines einzelnen Benutzers auf einem Post beizubehalten?

Solutions Collecting From Web of "Wie frage ich nach Beiträgen nach teilweisem Metaschlüssel?"

Leider können Sie keine meta_query mit einem LIKE Vergleich für den Wert WP_Query meta_key , wenn Sie WP_Query . Ich war auf dieser Straße …

Stattdessen haben Sie ein paar andere Optionen, wenn Sie wie Status-Beziehungen als Post-Meta und nicht als Benutzer-Meta und / oder Meta in einer benutzerdefinierten Tabelle beibehalten möchten.

Option 1

  • erfordert keine Änderung Ihres Meta-Schemas
  • verwendet die wpdb class, um eine benutzerdefinierte Abfrage auszuführen

Beispiel:

 //when a user likes a post... $current_user_id = get_current_user_id(); add_post_meta($current_user_id, "like_status_{$current_user_id}", 1, false); //later in the request... global $wpdb; $results = $wpdb->get_results( " SELECT meta_key FROM {$wpdb->prefix}postmeta WHERE meta_key LIKE 'like_status_%' ", ARRAY_N ); $results = array_map(function($value){ return (int) str_replace('like_status_', '', $value[0]); }, $results); array_walk($results, function($notify_user_id, $key){ //apply to all users except the user who just liked the post if ( $notify_user_id !== $current_user_id ) { //notify logic here... } }); 

Hinweis: Logik könnte weiter vereinfacht werden, wenn Sie es wünschen.

Option 2

  • erfordert, dass Sie Ihr Meta-Schema ändern
  • erfordert, dass Sie die Benutzer-ID als Metawert speichern
  • ermöglicht Ihnen, WP_Query zusammen mit meta_query

Option 2 erfordert, dass Sie Ihren like_status_{user_id} von like_status_{user_id} zu etwas Universellem wie like_status oder liked_by_user_id wobei Sie anstatt den Wert 1 für den Schlüssel zu speichern, stattdessen die ID des Benutzers als Wert speichern.

 //when a user likes a post... $current_user_id = get_current_user_id(); add_post_meta($current_user_id, "liked_by_user_id", $current_user_id, false); //later in the request $args = array( 'post_type' => 'post', //or a post type of your choosing 'posts_per_page' => -1, 'meta_query' => array( array( 'key' => 'liked_by_user_id', 'value' => 0, 'type' => 'numeric' 'compare' => '>' ) ) ); $query = new WP_Query($args); array_walk($query->posts, function($post, $key){ $user_ids = get_post_meta($post->ID, 'liked_by_user_id'); array_walk($user_ids, function($notify_user_id, $key){ //notify all users except the user who just like the post if ( $notify_user_id !== $current_user_id ) { //notify logic here... //get user eg $user = get_user_by('id', $notify_user_id); } }); }); 

Es ist ziemlich schwierig, Ihre Frage konkret zu beantworten. Der erste Teil ist jedoch einfach. Ich habe kürzlich etwas Ähnliches im Stackoverflow gemacht

Metaschlüssel werden verglichen und stimmen genau überein. WP_Query hat keine Möglichkeit, dieses Verhalten mit einem einfachen Parameter anzupassen, aber wir können immer selbst einen einführen und dann die posts_where Klausel anpassen, um einen LIKE Vergleich für posts_where .

DER FILTER

Dies ist nur ein einfacher Filter, passen Sie ihn nach Bedarf an.

 add_filter( 'posts_where', function ( $where, \WP_Query $q ) { // Check for our custom query var if ( true !== $q->get( 'wildcard_on_key' ) ) return $where; // Lets filter the clause $where = str_replace( 'meta_key =', 'meta_key LIKE', $where ); return $where; }, 10, 2 ); 

Wie Sie sehen, wird der Filter nur ausgetriggers, wenn wir unseren neuen benutzerdefinierten Parameter wildcard_on_key auf true . Wenn das auscheckt, ändern wir einfach den = Komparator zum LIKE Komparator

Nur eine Anmerkung zu diesem, LIKE Vergleiche sind von Natur aus teurer, diese anderen Vergleiche zu führen

DIE ABFRAGE

Sie können Ihre Posts einfach wie folgt abfragen, um alle Posts mit like_status_{user_id} zu erhalten: like_status_{user_id}

 $args = [ 'wildcard_on_key' => true, 'meta_query' => [ [ 'key' => 'like_status_', 'value' => 1, ] ] ]; $query = new WP_Query( $args ); 

ANDERE FRAGE

Benutzerdefinierte Felder haben keinen Einfluss auf die performance. Sie können meinen Beitrag zu diesem Thema hier lesen. Ich bin jedoch beunruhigt darüber, dass Sie sagen, dass jeder Beitrag Hunderte oder Tausende von Likes haben kann. Dies kann Sie bei der performance beeinträchtigen, indem Sie so viele benutzerdefinierte Felddaten abrufen und zwischenspeichern. Es kann auch Ihre database mit einer großen Menge von unnötigen benutzerdefinierten Feld Daten verstopfen, die es ziemlich schwer zu pflegen macht.

Ich bin kein großer Fan von serialisierten Daten in benutzerdefinierten Feldern zu speichern, da man nicht durch serialisierte Daten suchen oder bestellen kann. Ich würde jedoch vorschlagen, alle Benutzer-IDs in einem Array unter einem benutzerdefinierten Feld zu speichern. Sie können das Array einfach mit der Benutzer-ID aktualisieren, wenn ein Benutzer einen Beitrag wünscht. Die Daten des benutzerdefinierten Felds abzufragen und das Array von IDs zu durchlaufen und etwas mit den IDs zu tun, sind einfach. get_post_meta() einen Blick auf get_post_meta()

Das Aktualisieren eines benutzerdefinierten Felds ist ebenfalls einfach. Dafür müssen Sie in update_post_meta() suchen, ich weiß nicht, wie Sie Ihre benutzerdefinierten Felder erstellen, aber update_post_meta() ist definitiv etwas, das Sie verwenden möchten.

Wenn Sie beim Aktualisieren eines benutzerdefinierten Felds E-Mails senden oder Push-Benachrichtigungen senden müssen, stehen Ihnen die folgenden Hooks zur Verfügung, mit denen Sie arbeiten können. ( Siehe update_metadata() für den Kontext )

  • update_postmeta

  • aktualisiert _ {$ meta_type} _meta

  • aktualisierte_postmeta

  • Aktualisieren Sie _ {$ meta_type} _meta

  • Aktualisieren Sie _ {$ meta_type} _metadata

FAZIT

Bevor Sie die serialisierte Route veröffentlichen, stellen Sie sicher, dass Sie nicht nach den sortierten Daten sortieren oder nach bestimmten Daten in den serialisierten Daten suchen müssen.

Wenn Sie dies später erweitern möchten, mit detaillierteren Statistiken, functionen usw., dann könnte eine weitere Alternative sein: benutzerdefinierte Tabelle (n)

  • Profis : Auf Ihre Bedürfnisse zugeschnitten und können für eine bessere performance indiziert werden .

  • Nachteile : Mehr Arbeit

Es kann auch eine Problemumgehung mit einer benutzerdefinierten Taxonomie geben, die eine bessere Abfrageleistung bietet als Post-Meta-Abfragen, da die coretabellen indexiert sind.

Ich versuche, eine Benachrichtigung an alle zu schicken, die einen Beitrag gemocht haben, wenn jemand anderen diesen Beitrag mag … etwas wie “Hey, jemand anders hat diesen Beitrag gemocht, den du magst. Du solltest es ausprobieren!” Aber ich brauche einen Weg, um herauszufinden, ob jemand anderen diesen Beitrag gefallen hat und wenn ja, wer sie sein würden, damit ich sie benachrichtigen könnte.

Nicht sicher, welche Art von Benachrichtigungen Sie hier meinen, aber das kann schnell sperrig werden.

Beispiel : Ein Benutzer, der ~ 1000 Posts mag und jeder Post ~ 1000 Likes erhält, dann gibt es 1M Notifications in den Pipes, nur für diesen Benutzer! Wenn dies E-Mail-Benachrichtigungen sind, ist der Host-Anbieter möglicherweise nicht zufrieden und der Benutzer wird verrückt. Das könnte auch mit einem E-Mail-Dienst von Drittanbietern teuer sein.

In der WP_Meta_Query- Dokumentation können Sie das Argument compare Argument meta_query von WP_Query verwenden. Sie können jedoch nur den value und nicht den key daher sollten Sie vielleicht überdenken, wie Sie dies strukturieren.

Ein like Argument würde so aussehen:

 $arguments = array( 'meta_query' => array( array( 'key' => 'foo', 'value' => 'ba', 'compare' => 'LIKE' ) ) ); $query = new WP_Query($arguments); 

Da Sie keine “LIKE” Suche nach dem key würde ich vorschlagen, dass Sie die geliebten Beiträge im Benutzer-Meta hinzufügen und eine WP_User_Query Suche für Nutzer durchführen, die diesen Beitrag gemocht haben:

 $arguments = array( 'meta_query' => array( array( 'key' => 'liked_post', 'value' => '' ) ) ); $users = new WP_User_Query($arguments);