Meta_field olarak bir diziyle nasıl meta_query oluşturabilirim?


16

İşte benim sorgu için argümanlar:

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => 'sports',
        )
    )
);

Bu topicsbir dize olduğunda çalışır , ancak bir dizi olduğunda çalışmaz . Bu sorgunun topicsörneğin ne zaman çalışmasını istiyorumarray( 'sports', 'nonprofit', etc. )

Meta_key olarak dizilerle meta sorgular oluşturmanın bir yolu var mı?


Lütfen açıklığa kavuşturun - "konular" ın saklanan değerinin bir dizi olduğu anlamına mı geliyor ? Ya da depolanan değerin bir dize olduğunu ve bir dizideki sorguya birden çok terim iletmek mi istiyorsunuz?
MathSmath

@MathSmath, saklanan değerin bir dizi olduğunu kastediyorum.
mike23

Yanıtlar:


31

Sorguyu bir dizi olası değerle besleme

Veritabanındaki değer bir dize ise ve sorguyu birkaç değerle beslemek istiyorsanız:

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => array ( 'sports', 'nonprofit', 'community' ),
            'compare' => 'IN'
        )
    )
);

Serileştirilmiş bir veri dizisinde belirli bir değeri arama

Veritabanındaki değer birkaç konudan oluşan bir diziyse ve bu dizi içinde tek bir konu aramak istiyorsanız (Veritabanındaki bir dizinin bu şekilde alınabileceğini, ancak veritabanında serileştirilmiş biçimde yaşadığını unutmayın. string ayrıca):

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => 'sports',
            'compare' => 'LIKE'
        )
    )
);

Karşılaştırma değeri olarak 'GİBİ' kullanmak, umduğunuz kadar açık bir talimat değildir, ancak gitmek için en iyi seçenektir.

Bunun yanında, diğer tek seçeneğiniz meta_key "konular" ayarlanmış tüm yayınları almak ve bunları manuel olarak yinelemek veya başka bir deyişle döngü içindeki değeri kontrol etmek ve yayınları belirtilen koşulda görüntülemek olacaktır.


14

Johannes'in yanıtından çıkmak için, seri hale getirilmiş bir dizi olduğu için, kullanıcı kimlikleri (benim durumumdu) gibi bir şey saklıyorsanız, bunu biraz farklı ele almanız gerekebilir.

Yayın meta şu şekilde kaydediliyordu:

array( "1", "23", "99");

Yani evet tamsayıdırlar ama update_post_metadizgiler olarak kaydedilmişlerdir.

'meta_query' => array(
            array(
                    'key'     => 'my_meta_key',
                    'value'   => serialize( strval( 1 ) ),
                    'compare' => 'LIKE'
                )
            )

Yani aslında aradığınız şeyin serileştirilmiş dize sürümü ile LIKE karşılaştırması yapıyorsunuz. Çalışmak için böyle bir şey almaya çalışırken iyi bir kaç saat geçirdim ve şimdiye kadar bu gelip iyi oldu.


serialize (strval (1)) sorunumu çözdü, teşekkürler
Behzad

Bugün şans eseri bu eski cevaba rastladı. Eklemenizi seviyorum. +1
Johannes Pille

Ben de bu rastladım, benim şey kullanıcı_id dizi değil tüm mesajlar almak gerekir, ancak yukarıdaki çözüm işe yaramaz, bu yüzden böyle yaptım: 'meta_query' => array( array( 'key' => 'my_meta_key', 'value' => ':' . $user_id . ';', 'compare' => 'NOT LIKE' ) ) Çünkü serileştirildiğinde tüm değerler gibi kaydedilir: ' : değer;'
Bobz

4

@Syles'in cevabından bir başka hafif gelişme.

Kimlikleri hem dizeleri (örneğin bir form girişinden alındığında) hem de tamsayılar (örneğin update_post_meta($post_id, authorized_users', array(get_current_user_id()));) olarak saklandığı durumlarda oldu . Bu, wp_set_object_terms()terimleri ayarlamak için terim kimliklerini kullanabileceğiniz iyi bilinen bir sorun gibidir , ancak bunları tamsayı olarak kullanmazsanız, bu numaralarla isimleri olarak yeni terimler oluşturma şansınız yaklaşık% 50'dir. yerine.

Bu, test sitemin veritabanından sadece böyle bir durumun alıntılarından görülebileceği gibi, serileştirilmiş bir dizide oldukça farklı depolanmalarına neden olabilir:

a:1:{i:0;s:1:"1";} // 's' for 'string', also note the double quotes
a:1:{i:0;i:1;} // 'i' for 'integer', no quotes

Yukarıdakilerin her ikisi yoluyla beslendiğinde print_r()olarak oluşturulur

Array
(
    [0] => 1
)

Bunu düzeltmek için , değeri bir dize yerine bir tamsayı olarak kullanan sorgunun ve başka bir sürümünü meta_queryekleyerek hafif bir değişiklik yaptım relation.

İşte nihai sonuç:

        'meta_query' => array(
            'relation' => 'OR', // Lets it know that either of the following is acceptable
            array(
                'key' => 'bcm_enm_authorized_users',
                'value'   => serialize(strval(get_current_user_id())), // Saved as string
                'compare' => 'LIKE'
            ),
            array(
                'key' => 'bcm_enm_authorized_users',
                'value'   => serialize(intval(get_current_user_id())), // Saved as integer
                'compare' => 'LIKE'
            ),
        ),

DÜZENLEME: Bu yöntemin dizi dizinleri ile çarpışma riskini taşıyabildiğini fark etti, bu da birisinin dizide bulunmaması durumunda malzemelere yasadışı erişmesine izin verebilir, ancak kullanıcı kimliği bir dizin olarak görünür. Bu süre Bunun gibi, işler Aynı sorunu ele varsa, daha iyi bir uygulama herhangi bir değerin bu kadar yerine @sMyles' yöntemi kullanabileceklerini kaydederek öncesinde dizeleri olarak dökme aramak istediğiniz sağlamaktır.


Bu seçilen cevap olmalı, en güvenilir
Amin

2

Johannes'in cevabına giderdim. Ancak, bu meta_query kullanarak, böyle bir vaka karşılayacak çünkü geliştirmek istiyorum

senin değerin

array('sports','movies', 'sports2');

aradığın zaman

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => 'sports',
            'compare' => 'LIKE'
        )
    )
);

sonuç hem 'spor' hem de 'spor2' döndürecektir.

Bunu düzeltmek için meta_query argümanlarını

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => 'sports";',
            'compare' => 'LIKE'
        )
    )
);

Bunun nedeni, değerin veritabanında serileştirilmesi ve her öğenin noktalı virgülle ayrılmasıdır. Böylece yukarıdaki argümanlar işe yarayacak

Değerdeki öğeler sayı ise, çift tırnak işaretini kaldırmanız yeterlidir "

$args = array(
        'post_type' => 'news',
        'meta_query' => array(
            array(
                'key' => 'topics',
                'value' => '1;',
                'compare' => 'LIKE'
            )
        )
    );

1

Bugün benzer bir şeyle güldüm. Birden fazla ilgili kullanıcı (dizi) ile bir ACF (Gelişmiş Özel Alanlar) ilişki alanını sorgulamak zorunda.

Php üzerinden alan güncelledikten sonra sorgu çalışmadı. ACF kullanıcı arayüzü üzerinden güncelledikten sonra sorgu çalıştı.

Sorun, benim php kod ilişki değerleri int-değerleri olarak ayarlamak, UI dize değerlerine ayarlamak oldu. Her ikisinin de çalıştığından emin olmak için şimdi bu sorguyu kullanıyorum (buradaki örneğe takılı):

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key' => 'topics',
            'value' => '1;',  // works for int-array
            'compare' => 'LIKE'
        ),
        array(
            'key' => 'topics',
            'value' => '"1"',  // works for string-array
            'compare' => 'LIKE'
        ),
    )
);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.