it-swarm.com.de

Wie frage ich Beiträge nach Teilmetaschlüsseln ab?

Ich habe eine Funktion, die den "Gefällt mir" -Status eines Posts als Post-Meta speichert. Ich möchte dieses "Gefällt mir" mit dem Benutzer verknüpfen, dem es gefallen hat. Daher richte ich ein benutzerdefiniertes Feld mit dem Namen "like_status_ {user_id}" ein (wobei {user_id} die ID des derzeit angemeldeten Benutzers ist), das ich als 0 oder 0 speichere 1. Für einen Post mit mehreren "Likes" gäbe es also mehrere Meta-Werte in der Datenbank, die wie folgt eingerichtet sind:

'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 möglicherweise Tausende von Likes für einen bestimmten Beitrag. Wie würde ich eine Abfrage ausführen, die zeigt, ob jemand anderem dieser Beitrag gefällt?

Ich dachte so etwas:

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

Ich versuche, eine Benachrichtigung an alle zu senden, denen ein Beitrag gefallen hat, wenn jemand anderem dieser Beitrag gefällt ... so etwas wie "Hey, jemand anderem hat dieser Beitrag gefallen, den Sie gefallen haben. Sie sollten ihn sich ansehen!" Aber ich brauche einen Weg, um herauszufinden, ob jemandem dieser Beitrag gefallen hat und wenn ja, wer er wäre, könnte ich ihn benachrichtigen.

Wenn dies nicht möglich ist, können Sie eine bessere Methode zum Speichern dieser Daten als post_meta vorschlagen und gleichzeitig die Effizienz beibehalten, mit der der Status eines einzelnen Benutzers für einen Beitrag schnell aktualisiert werden kann?

8
codescribblr

Leider können Sie bei Verwendung von meta_query keinen meta_key mit einem LIKE-Vergleich für den WP_Query-Wert durchführen. Ich war auf diesem Weg ...

Stattdessen haben Sie einige andere Optionen, wenn Sie ähnliche Statusbeziehungen als Post-Meta und nicht als Benutzer-Meta und/oder Meta in einer benutzerdefinierten Tabelle beibehalten möchten.

Option 1

  • erfordert keine Änderung Ihres Metaschemas
  • verwendet die Klasse wpdb, um eine benutzerdefinierte Abfrage durchzufü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: Die Logik kann auf Wunsch weiter vereinfacht werden.

Option 2

  • erfordert, dass Sie Ihr Metaschema ändern
  • erfordert, dass Sie die Benutzer-ID als Meta-Wert speichern
  • ermöglicht die Verwendung von WP_Query zusammen mit meta_query

Option 2 erfordert, dass Sie Ihren Metaschlüssel von like_status_{user_id} in einen universellen Schlüssel wie like_status oder liked_by_user_id ändern. Statt den Wert von 1 für den Schlüssel zu speichern, speichern Sie stattdessen die ID des Benutzers als Wert.

//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 e.g. $user = get_user_by('id', $notify_user_id);

        }

    });

});
6
userabuser

Es ist ziemlich schwierig, Ihre Frage konkret zu beantworten. Der erste Teil ist jedoch einfach. Ich habe vor kurzem etwas gemacht ähnlich wie bei stackoverflow

Metaschlüssel werden verglichen und stimmen genau überein. WP_Query hat keine Möglichkeit, dieses Verhalten mit einem einfachen Parameter anzupassen. Wir können uns jedoch jederzeit einen vorstellen und dann die posts_where-Klausel anpassen, um einen LIKE-Vergleich für Metaschlüssel durchzuführen.

DER FILTER

Dies ist nur ein grundlegender 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 ausgelöst, wenn wir unseren neuen benutzerdefinierten Parameter wildcard_on_key auf true setzen. Wenn dies auscheckt, ändern wir einfach den =-Komparator in den LIKE-Komparator

Nur eine Anmerkung dazu: LIKE Vergleiche sind von Natur aus teurer als andere Vergleiche

DIE ABFRAGE

Sie können Ihre Beiträge einfach wie folgt abfragen, um alle Beiträge mit Metaschlüsseln 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 Leistung. Sie können meinen Beitrag zu diesem Thema lesen hier . Ich bin jedoch beunruhigt darüber, dass Sie sagen, dass jeder Beitrag Hunderte oder Tausende von Likes haben kann. Dies kann sich negativ auf das Abrufen und Zwischenspeichern einer so großen Menge benutzerdefinierter Felddaten auswirken. Es kann auch Ihre Datenbank mit einer großen Menge an unnötigen benutzerdefinierten Felddaten verstopfen, was die Wartung ziemlich schwierig macht.

Ich bin kein großer Fan von Speichern serialisierter Daten in benutzerdefinierten Feldern, da nach serialisierten Daten nicht gesucht oder bestellt werden 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 mag. Das Abrufen der benutzerdefinierten Felddaten und das Durchlaufen des Arrays von IDs und das Ausführen von Aktionen mit den IDs sind einfach. Schauen Sie sich einfach get_post_meta() an.

Das Aktualisieren eines benutzerdefinierten Felds ist ebenfalls einfach. Dazu müssen Sie sich mit update_post_meta() befassen. Ich weiß nicht, wie Sie Ihre benutzerdefinierten Felder erstellen, aber update_post_meta() ist definitiv etwas, das Sie verwenden möchten.

Wenn Sie E-Mails oder Push-Benachrichtigungen senden müssen, wenn ein benutzerdefiniertes Feld aktualisiert wird, können Sie mit den folgenden Hooks arbeiten. ( Siehe update_metadata() für den Kontext )

FAZIT

Bevor ich dies wieder veröffentliche, stellen Sie sicher, dass Sie nicht nach den sortierten Daten sortieren oder nach bestimmten Daten in den serialisierten Daten suchen müssen, bevor Sie die serialisierte Route gehen.

10
Pieter Goosen

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

  • Profis : Auf Ihre Bedürfnisse zugeschnitten und können indexiert werden, um eine bessere Leistung zu erzielen.

  • cons : Mehr Arbeit

Möglicherweise gibt es auch eine Problemumgehung mit einer benutzerdefinierten Taxonomie, die aufgrund der Indizierung der Kerntabellen eine bessere Abfrageleistung bietet als Post-Meta-Abfragen.

Ich versuche, eine Benachrichtigung an alle zu senden, denen ein Beitrag gefallen hat, wenn jemand anderem dieser Beitrag gefällt ... so etwas wie "Hey, jemand anderem hat dieser Beitrag gefallen, den Sie gefallen haben. Sie sollten ihn sich ansehen!" Aber ich brauche einen Weg, um herauszufinden, ob jemandem dieser Beitrag gefallen hat und wenn ja, wer er wäre, könnte ich ihn benachrichtigen.

Nicht sicher, welche Art von Benachrichtigungen Sie hier meinen, aber dies kann schnell unhandlich werden.

Beispiel : Ein Benutzer, der ~ 1000 Posts mag und jeder Post ~ 1000 Likes bekommt, dann gibt es 1 Million Benachrichtigungen 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. Dies kann auch bei einem E-Mail-Dienst eines Drittanbieters teuer sein.

2
birgire

Seit WordPress 5.1 ist es nun möglich, Meta-Abfragen wie die folgenden zu verwenden: enter image description here

1
K. Tromp

In der WP_Meta_Query Dokumentation können Sie das Argument compare im Argument meta_query von WP_Query verwenden. Sie können jedoch nur die value und nicht die key vergleichen, sodass Sie möglicherweise überdenken möchten, 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 in der key keine 'LIKE'-Suche durchführen können, empfehlen wir Ihnen, die gewünschten Beiträge in das Benutzer-Meta aufzunehmen und eine WP_User_Query -Suche nach Benutzern durchzuführen, denen dieser Beitrag gefallen hat:

$arguments = array(
    'meta_query' => array(
        array(
            'key' => 'liked_post',
            'value' => '<post_id>'
        )
    )
);

$users = new WP_User_Query($arguments);
0
LonnyLot