получение всех значений для ключа настраиваемого поля (кросс-пост)
-
-
Похоже,вы используете это как таксономию.Почему бы просто (автоматически) не добавить термин к этим сообщениям при сохранении?Сделал бы запросы намного проще.Seems like you're using this as a taxonomy. Why not simply (automatically) add a term to these posts when saving? Would make querying a lot easier.
- 5
- 2011-02-15
- kaiser
-
@kaiser Я не могу отблагодарить тебя за то,что ты гений!@kaiser I can't thank you enough for being a genius!
- 0
- 2016-10-26
- user2128576
-
7 ответ
- голосов
-
- 2011-02-15
Один из возможных подходов - использовать один из вспомогательных методов в классе WPDB для выполнения более точного запроса на основе метаданных. Однако предостережение при использовании некоторых из этих функций заключается в том,что вы обычно не получаете обратно простой массив данных и обычно должны делать ненужные ссылки на свойства объекта,даже если вы вызываете только один столбец или строку.
Конечно,не все функции являются одними и теми же,и целенаправленно упоминается метод WPDB ,
get_col
,который возвращает простой плоский массив данные,для которых запрашиваются данные,я специально упоминаю об этом,потому что следующий пример будет вызывать этот метод.WordPress - WPDB Выбор столбца данных
$ wpdb->get_col ()Вот пример функции,которая запрашивает в базе данных все сообщения выбранного типа,статуса публикации и с определенным мета-ключом (или настраиваемым полем для менее технически подкованных).
function get_meta_values( $key = '', $type = 'post', $status = 'publish' ) { global $wpdb; if( empty( $key ) ) return; $r = $wpdb->get_col( $wpdb->prepare( " SELECT pm.meta_value FROM {$wpdb->postmeta} pm LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND p.post_status = %s AND p.post_type = %s ", $key, $status, $type ) ); return $r; }
Так,например,если вы хотите узнать,какие сообщения имеют мета-ключ rating ,для типа сообщения фильмы и вы хотите сохранить эту информацию внутри переменной,примером такого вызова может быть ..
$movie_ratings = get_meta_values( 'rating', 'movies' );
Если вы не хотите делать ничего,кроме вывода этих данных на экран,функция PHPimplode может быстро разделить этот простой массив на строки данных.
// Print the meta values seperate by a line break echo implode( '<br />', get_meta_values( 'YOURKEY' ));
Вы также можете использовать возвращенные данные,чтобы определить,сколько сообщений имеют эти мета-значения,например,выполнив простой цикл по возвращенным данным и построив массив счетчиков.
$movie_ratings = get_meta_values( 'rating', 'movies' ); if( !empty( $movie_ratings ) ) { $num_of_ratings = array(); foreach( $movie_ratings as $meta_value ) $num_of_ratings[$meta_value] = ( isset( $num_of_ratings[$meta_value] ) ) ? $num_of_ratings[$meta_value] + 1 : 1; } /* Result: Array( [5] => 10 [9] => 2 ) // ie. there are 10 movie posts with a rating of 5 and 2 movie posts with a rating of 9. */
Эту логику можно применять к различным типам данных и расширять для работы любым количеством различных способов. Так что я надеюсь,что мои примеры были полезными и достаточно простыми,чтобы следовать им.
One possible approach would be to use one of the helper methods in the WPDB class to do a more refined meta based query. The caveat to using some of these functions however, is that you don't usually get back a simple array of data and usually have to make needless references to object properties, even if you're only calling for one column or row.
Of course, not all functions are the one and the same, and a purposeful mention goes out to the WPDB method,
get_col
which returns a simple flat array of the data queried for, i make this mention specifically because the example following will call upon this method.WordPress - WPDB Selecting a column of data
$wpdb->get_col()Here's an example function which queries the database for all posts of a chosen post type, post status and with a specific meta key(or custom field to the less technically minded).
function get_meta_values( $key = '', $type = 'post', $status = 'publish' ) { global $wpdb; if( empty( $key ) ) return; $r = $wpdb->get_col( $wpdb->prepare( " SELECT pm.meta_value FROM {$wpdb->postmeta} pm LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND p.post_status = %s AND p.post_type = %s ", $key, $status, $type ) ); return $r; }
So for example, if you like to find out which posts have a meta key of rating, for the post type movies and you'd like to store that information inside a variable, an example of such a call would be..
$movie_ratings = get_meta_values( 'rating', 'movies' );
If you wanted to do nothing more than print that data to screen, PHP's implode function can quickly splice that simple array into lines of data.
// Print the meta values seperate by a line break echo implode( '<br />', get_meta_values( 'YOURKEY' ));
You can also use the returned data to work out how many posts have these meta values by doing a simple loop over the returned data and building an array of the counts, for example.
$movie_ratings = get_meta_values( 'rating', 'movies' ); if( !empty( $movie_ratings ) ) { $num_of_ratings = array(); foreach( $movie_ratings as $meta_value ) $num_of_ratings[$meta_value] = ( isset( $num_of_ratings[$meta_value] ) ) ? $num_of_ratings[$meta_value] + 1 : 1; } /* Result: Array( [5] => 10 [9] => 2 ) // ie. there are 10 movie posts with a rating of 5 and 2 movie posts with a rating of 9. */
This logic could be applied to various kinds of data, and extended to work any number of different ways. So i hope my examples have been helpful and simple enough to follow.
-
Также забавный факт для будущих зрителей,если вы хотите получать только уникальные мета-значения - вы набираете `DISTINCT` сразу после` SELECT` в функции выше.Может быть полезно.Also fun-fact for future viewers, if you want to pull only Unique meta values - you type `DISTINCT` right after the `SELECT` in the function above. Could be useful.
- 3
- 2014-02-07
- Howdy_McGee
-
Я думаю это очень полезноI think this is extremely useful
- 0
- 2017-05-01
- Pablo S G Pacheco
-
Как это сделать и вернуть отсортированные значения? Я думаю,что с помощью ORDERby,но я не могу понять,как его использоватьHow to do this, and return the values sorted?, I think that using ORDER by but I cant figure out how to use it
- 0
- 2018-04-17
- efirvida
-
- 2011-06-05
Я просто хотел бы добавить одну мелочь в приведенный выше код t31os .Я изменил "SELECT" на "SELECT DISTINCT",чтобы исключить повторяющиеся записи,когда я сам использовал этот код.
I'd just like to add one tiny thing to t31os's code above. I changed "SELECT" into "SELECT DISTINCT" to eliminate duplicate entries when I used this code myself.
-
Я могу представить себе случаи,когда было бы допустимо иметь несколько мета-значений одного и того же значения,и поэтому я не вносил это дополнение в свой код.Если вам нужны разные значения,это будет лучший вариант.Кроме того,вы также можете добавить это в качестве аргумента для функции (чтобы вы могли использовать его или нет,в зависимости от ситуации).I can imagine cases where it would be valid to have multiple meta values of the same value, and thus didn't not make that addition to my code. If you want distinct values, this would be the way to go though. Additionally you could also add that in as an argument for the function(so you can use it or not, as appropriate).
- 1
- 2014-01-24
- t31os
-
- 2015-10-03
Использование глобального $ wpdb нецелесообразно или необходимо:
// function to grab all possible meta values of the chosen meta key. function get_meta_values( $meta_key, $post_type = 'post' ) { $posts = get_posts( array( 'post_type' => $post_type, 'meta_key' => $meta_key, 'posts_per_page' => -1, ) ); $meta_values = array(); foreach( $posts as $post ) { $meta_values[] = get_post_meta( $post->ID, $meta_key, true ); } return $meta_values; } $meta_values = get_meta_values( $meta_key, $post_type );
It is not good or needed to use the global $wpdb:
// function to grab all possible meta values of the chosen meta key. function get_meta_values( $meta_key, $post_type = 'post' ) { $posts = get_posts( array( 'post_type' => $post_type, 'meta_key' => $meta_key, 'posts_per_page' => -1, ) ); $meta_values = array(); foreach( $posts as $post ) { $meta_values[] = get_post_meta( $post->ID, $meta_key, true ); } return $meta_values; } $meta_values = get_meta_values( $meta_key, $post_type );
-
В большинстве случаев это был бы мой предпочтительный метод.Он выполняет пять запросов,а не один,но,поскольку он использует стандартные процедуры WordPress для их генерации и отправки,сработает любое кэширование для конкретной платформы (например,кэширование объектов WP Engine или какой-либо случайный плагин). Данные также будутбудут храниться во внутреннем кеше WordPress на время выполнения запроса,поэтому при необходимости не потребуется повторно получать данные из базы данных.This would be my preferred method of doing it, in most cases. It makes five queries, rather than just one, but, as it's using the standard WordPress procedures to generate and submit them, any platform-specific caching (such as WP Engine's Object Caching or some random plugin) will kick in. The data will also be stored in WordPress' internal cache for the duration of the request, so will not need to be retrieved from the database again, if needed.
- 0
- 2017-06-02
- Andrew Dinmore
-
К данным также будут применяться любые фильтры,что может быть чрезвычайно важно,например,на многоязычном сайте.Наконец,поскольку он использует только стандартные базовые функции WordPress,гораздо менее вероятно,что он будет сломан в будущем обновлении.Any filters will also be applied to the data, which could be extremely important on, for example, a multi-lingual site. Lastly, since it's using just standard WordPress core functions, it's much less likely to be broken by a future update.
- 0
- 2017-06-02
- Andrew Dinmore
-
Это можно было бы сделать более производительным,ограничив запрос идентификатором публикации? Добавить: 'fields'=> 'ids'` Итак,массив запросов будет выглядеть так: `` `массив ( 'post_type'=> $post_type, 'meta_key'=> $meta_key, 'posts_per_page'=> -1, 'fields'=> 'ids' ) `` `This might be made more performant by limiting the query to post id? Add: `'fields' => 'ids'` So, the query array would look like: ```array( 'post_type' => $post_type, 'meta_key' => $meta_key, 'posts_per_page' => -1, 'fields' => 'ids' )```
- 1
- 2020-04-13
- Pea
-
Внимание: это также отфильтровывает мета-значения,которые существуют только в неопубликованных сообщениях,поэтому убедитесь,что вы используете аргументpost_status,чтобы эта функция не являлась ошибкой.Caution this also filters out meta values that exist only on not published posts so make sure you use the 'post_status' arg to make this a feature not a bug
- 0
- 2020-07-23
- jnhghy - Alexandru Jantea
-
- 2011-02-15
самым быстрым способом был бы пользовательский запрос sql,и я не уверен,но вы можете попробовать
$wpdb->get_results(" SELECT posts.* , COUNT(*) 'moodcount' FROM $wpdb->posts as posts JOIN $wpdb->postmeta as postmeta ON postmeta.post_id = posts.ID AND postmeta.meta_key = 'Mood' GROUP BY postmeta.meta_key ");
Если что,то это начало.
the fastest way would be a custom sql query and i'm not sure but you can try
$wpdb->get_results(" SELECT posts.* , COUNT(*) 'moodcount' FROM $wpdb->posts as posts JOIN $wpdb->postmeta as postmeta ON postmeta.post_id = posts.ID AND postmeta.meta_key = 'Mood' GROUP BY postmeta.meta_key ");
If anything then its a start.
-
спасибо,но не следует ли избегать пользовательских запросов «любой ценой»?Я бы предпочел использовать уровень абстракции WP (так он называется?) ... но,конечно,если это невозможно ...thanks, but shouldn't custom quesries be avoided 'at all cost'? I'd prefer to use the WP abstraction layer (is that what it's called?)... but of course if this is not possible..
- 1
- 2011-06-08
- mikkelbreum
-
Пользовательские запросы,если они написаны правильно,могут быть лучше,и вам следует избегать их,только если вы не знаете,что делаете.Custom queries, if written the right way, can be better and you should only avoid them if you don't know what you're doing.
- 0
- 2011-06-08
- Bainternet
-
Я согласен сmwb. Пользовательские запросы очень полезны и практичны,но я думаю,что они также намного тяжелее для БД .. особенно с использованием функций SRT ..I Agree with mwb .custom queries are very usefull and practical, but I think they are also much heavier on the DB.. especially using SRT functions..
- 1
- 2011-12-10
- krembo99
-
- 2013-09-07
Для получения всех мета-значений по мета-ключу
Проверить wp-> db wordpress codex
$values = $wpdb->get_col("SELECT meta_value FROM $wpdb->postmeta WHERE meta_key = 'yourmetakey'" );
For getting all meta values by a meta key
$values = $wpdb->get_col("SELECT meta_value FROM $wpdb->postmeta WHERE meta_key = 'yourmetakey'" );
-
Проблема с этим подходом заключается в отсутствии специфики,вы получите множество результатов от такого запроса,который может включать черновики,удаленные элементы,сообщения,страницы и любой другой существующий тип сообщений.Никогда не следует запрашивать то,что вам не нужно,здесь,безусловно,требуется конкретность.The issue with this approach is the lack of specificity, you'll get numerous results from such a query, which could include drafts, trashed items, posts, pages, and any other post type that exists. You should never query for what you don't need, specificity is most certainly required here.
- 3
- 2014-01-24
- t31os
-
Хотя это правда,что вы можете получать значения из других типов и статусов сообщений,бывают случаи,когда все,что вам нужно,это значения,и вы не использовали этотmeta_key нигде,кроме тех,где он вам нужен.Если все/большинство значений уникальны,это может быть лучшим решением.While it is true that you could get values from other post types and statuses, there are times when all you need are the values and you haven't used that meta_key anywhere but where you need it. If all/most values are unique, this may be the best solution.
- 0
- 2018-06-23
- Luke Gedeon
-
- 2012-01-31
Нет причин,по которым вы не можете объединитьt31os и код Bainternet,чтобы получить повторно используемый подготовленный оператор (стиль wordpress),который возвращает счетчик и значения за одну эффективную операцию.
Это настраиваемый запрос,но он по-прежнему использует уровень абстракции базы данных wordpress - поэтому,например,не имеет значения,какие на самом деле имена таблиц или меняются ли они,и это подготовленный оператор,поэтому мы намного безопаснее SQL-атаки и т. Д.
В этом случае я больше не проверяю тип сообщения и исключаю пустые строки:
$r = $wpdb->get_results( $wpdb->prepare( " SELECT pm.meta_value AS name, count(*) AS count FROM {$wpdb->postmeta} pm LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE pm.meta_key = '%s' AND pm.meta_value != '' AND p.post_type = '%s' GROUP BY pm.meta_value ORDER BY pm.meta_value ", $key, $type) ); return $r;
В частности,
Это вернет массив таких объектов:
array 0 => object(stdClass)[359] public 'name' => string 'Hamish' (length=6) public 'count' => string '3' (length=1) 1 => object(stdClass)[360] public 'name' => string 'Ida' (length=11) public 'count' => string '1' (length=1) 2 => object(stdClass)[361] public 'name' => string 'John' (length=12) public 'count' => string '1' (length=1)
There's no reason why you can't merge t31os and Bainternet's code to have a reusable prepared statement (wordpress style) that returns the count and the values in one efficient operation.
It's a custom query but it's still using the wordpress database abstraction layer - so for example it doesn't matter what the table names really are, or if they change, and it's a prepared statement so we're that much safer from SQL attacks etc.
In this instance I'm no longer checking for post type and I'm excluding empty strings:
$r = $wpdb->get_results( $wpdb->prepare( " SELECT pm.meta_value AS name, count(*) AS count FROM {$wpdb->postmeta} pm LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE pm.meta_key = '%s' AND pm.meta_value != '' AND p.post_type = '%s' GROUP BY pm.meta_value ORDER BY pm.meta_value ", $key, $type) ); return $r;
In this particular is
This will return an array of objects like so:
array 0 => object(stdClass)[359] public 'name' => string 'Hamish' (length=6) public 'count' => string '3' (length=1) 1 => object(stdClass)[360] public 'name' => string 'Ida' (length=11) public 'count' => string '1' (length=1) 2 => object(stdClass)[361] public 'name' => string 'John' (length=12) public 'count' => string '1' (length=1)
-
-
Обратите внимание,что это значение по умолчанию для текущего сообщения,когда не указанpost_id.Note that this defaults to the current post, when no post_id is specified.
- 0
- 2017-07-29
- birgire
-
Я знаю,как получить значение настраиваемого поля для конкретного сообщения.
Мне нужно получить все значения,связанные с конкретным настраиваемым ключом публикации, для всех сообщений .
Кто-нибудь знает эффективный способ сделать это?Я бы не хотел перебирать все идентификаторы сообщений в БД.
Пример:
4 сообщения с разными значениями настраиваемого поля "Настроение". 2 сообщения имеют значение "счастливый",1 сообщение - "сердитый" и 1 сообщение - "грустное"
Я хочу вывести: по всем сообщениям,которые у нас есть: два счастливых,один сердитый и один грустный автор (ы).
Но для МНОГО сообщений.
Я ищу: