একটি অনুসন্ধান ক্যোয়ারী ('গুলি') দিয়ে মেটা ক্যোয়ারী ('মেটা_কোয়ারি') ব্যবহার করা হচ্ছে


25

এমন অনুসন্ধান তৈরির চেষ্টা করছেন যা কেবল ডিফল্ট (শিরোনাম, সামগ্রী ইত্যাদি) অনুসন্ধান করে না তবে একটি নির্দিষ্ট কাস্টম ক্ষেত্রও সন্ধান করে।

আমার বর্তমান প্রশ্ন:

$args = array(
  'post_type' => 'post',
  's' => $query,
  'meta_query' => array(
     array(
       'key' => 'speel',
       'value' => $query,
       'compare' => 'LIKE'
     )
   )
);

$search = new WP_Query( $args )
...

এটি অনুসন্ধান ক্যোয়ারী এবং মেটা ক্যোয়ারী উভয়ের সাথে মেলে এমন পোস্টগুলি প্রত্যাবর্তন করে তবে আমি এটির পোস্টগুলিও ফেরত দিতে চাই যেখানে এটি যে কোনও একটির সাথে কেবল মেলে।

কোন ধারনা?


আপনি যা করতে চাইছেন তা কেবলমাত্র একটি অনুসন্ধান কোয়েরি ব্যবহার করে সম্ভব নয়। আপনার উভয় প্রশ্নের আলাদা আলাদাভাবে চালনা করতে হবে এবং তারপরে সেগুলি একত্রিত করতে হবে। এটি এই অন্যান্য উত্তরে বর্ণিত হয়েছে। এটি কীভাবে করবেন তা আপনার হাতে দেওয়া উচিত। ওয়ার্ডপ্রেস.স্ট্যাকেক্সেঞ্জঞ্জ
প্রশ্নগুলি /

উত্তর:


20

আমি এই সমস্যার সমাধানের জন্য কয়েক ঘন্টা অনুসন্ধান করে যাচ্ছি। অ্যারে মার্জিং যাওয়ার উপায় নয়, বিশেষত যখন প্রশ্নগুলি জটিল হয় এবং ভবিষ্যতে আপনাকে অবশ্যই মেটা প্রশ্নের সাথে যুক্ত করতে সক্ষম হবেন। সমাধানটি যা সরলতরূপে সুন্দর তা হ'ল 'এর' পরিবর্তন করা যা শিরোনাম এবং মেটা ক্ষেত্র উভয়ই সন্ধান করতে পারে।

add_action( 'pre_get_posts', function( $q )
{
    if( $title = $q->get( '_meta_or_title' ) )
    {
        add_filter( 'get_meta_sql', function( $sql ) use ( $title )
        {
            global $wpdb;

            // Only run once:
            static $nr = 0; 
            if( 0 != $nr++ ) return $sql;

            // Modified WHERE
            $sql['where'] = sprintf(
                " AND ( %s OR %s ) ",
                $wpdb->prepare( "{$wpdb->posts}.post_title like '%%%s%%'", $title),
                mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
            );

            return $sql;
        });
    }
});

ব্যবহার:

$meta_query = array();
$args = array();
$search_string = "test";

$meta_query[] = array(
    'key' => 'staff_name',
    'value' => $search_string,
    'compare' => 'LIKE'
);
$meta_query[] = array(
    'key' => 'staff_email',
    'value' => $search_string,
    'compare' => 'LIKE'
);

//if there is more than one meta query 'or' them
if(count($meta_query) > 1) {
    $meta_query['relation'] = 'OR';
}

// The Query
$args['post_type'] = "staff";
$args['_meta_or_title'] = $search_string; //not using 's' anymore
$args['meta_query'] = $meta_query;



$the_query = new WP_Query($args)

এটি সঠিক উপায়,
জোড়ক্স

কল্পনাপ্রসূত, এটি আমার পক্ষে খুব ভাল কাজ করেছে। দুর্দান্ত সমাধান! ধন্যবাদ!
ফাবিয়ানো

এটি একটি অনুসন্ধান, অনুসন্ধান নয়। আপনার যদি এমন প্লাগইন থাকে যা অনুসন্ধানে কাজ করে, এটি কাজ করে না। আমি কি ভূল?
marek.m

5

এই উত্তরের পরিবর্তিত সংস্করণ ব্যবহার করে প্রচুর কোড হ্রাস করা যায় ।

$q1 = new WP_Query( array(
    'post_type' => 'post',
    'posts_per_page' => -1,
    's' => $query
));

$q2 = new WP_Query( array(
    'post_type' => 'post',
    'posts_per_page' => -1,
    'meta_query' => array(
        array(
           'key' => 'speel',
           'value' => $query,
           'compare' => 'LIKE'
        )
     )
));

$result = new WP_Query();
$result->posts = array_unique( array_merge( $q1->posts, $q2->posts ), SORT_REGULAR );
$result->post_count = count( $result->posts );

এটি আমার জন্য দুর্দান্ত কাজ করেছে (বিশেষত যেহেতু আমার get_posts এর পরিবর্তে WP_Query ব্যবহার করা দরকার)। আমাকে আপনার পোস্ট_কাউন্টের লাইনটি সংশোধন করতে $result->post_count = count( $result->posts );হয়েছিল : কারণ আমি অন্যথায় কেবল 1 ফলাফল পাচ্ছিলাম।
গ্রেটব্লাকস

4

আমি @ স্টাবির কিরাকে কিছুটা উত্তর দিয়েছি optim

function wp78649_extend_search( $query ) {
    $search_term = filter_input( INPUT_GET, 's', FILTER_SANITIZE_NUMBER_INT) ?: 0;
    if (
        $query->is_search
        && !is_admin()
        && $query->is_main_query()
        && //your extra condition
    ) {
        $query->set('meta_query', [
            [
                'key' => 'meta_key',
                'value' => $search_term,
                'compare' => '='
            ]
        ]);

        add_filter( 'get_meta_sql', function( $sql )
        {
            global $wpdb;

            static $nr = 0;
            if( 0 != $nr++ ) return $sql;

            $sql['where'] = mb_eregi_replace( '^ AND', ' OR', $sql['where']);

            return $sql;
        });
    }
    return $query;
}
add_action( 'pre_get_posts', 'wp78649_extend_search');

এখন আপনি (শিরোনাম, বিষয়বস্তু, উত্সাহিত) বা (মেটা ক্ষেত্র) বা (উভয়ই) অনুসন্ধান করতে পারেন।


3

অনুযায়ী নিক পার্কিনস ' প্রস্তাবনা, আমি তাই মত দুই প্রশ্নের একত্রীকরণ ছিল:

$q1 = get_posts(array(
        'fields' => 'ids',
        'post_type' => 'post',
        's' => $query
));

$q2 = get_posts(array(
        'fields' => 'ids',
        'post_type' => 'post',
        'meta_query' => array(
            array(
               'key' => 'speel',
               'value' => $query,
               'compare' => 'LIKE'
            )
         )
));

$unique = array_unique( array_merge( $q1, $q2 ) );

$posts = get_posts(array(
    'post_type' => 'posts',
    'post__in' => $unique,
    'post_status' => 'publish',
    'posts_per_page' => -1
));

if( $posts ) : foreach( $posts as $post ) :
     setup_postdata($post);

     // now use standard loop functions like the_title() etc.     

enforeach; endif;

1
এটি কি এখনও 2016 সালে মার্জ না করে সম্ভব নয়? আমি pre_get_posts এর মাধ্যমে অনুসন্ধান ক্যোয়ারীটি সম্পাদনা করছি, সুতরাং এটি সত্যিই কোনও বিকল্প নয় ...
ট্রেইনোসিস

পছন্দ করুন আমি গত ২ ঘন্টা ধরে এটি চেষ্টা করে চলেছি এবং একটি গুগল অনুসন্ধান আমাকে এখানে পেয়েছে।
উমাইর খান যাদুন

2

ওয়েল এটি একটি হ্যাক ধরনের কিন্তু এটি কাজ করে। আপনার পোস্ট_ক্লেজ ফিল্টার যুক্ত করতে হবে। এই ফিল্টার ফাংশন চেকটি কাস্টম শব্দের যে কোনও একটির জন্য কাস্টম ফিল্ড "বানান" তে বিদ্যমান এবং বাকী ক্যোয়ারী অক্ষত থাকবে।

function custom_search_where($pieces) {

    // filter for your query
    if (is_search() && !is_admin()) {

        global $wpdb;

        $keywords = explode(' ', get_query_var('s'));
        $query = "";
        foreach ($keywords as $word) {

            // skip possible adverbs and numbers
            if (is_numeric($word) || strlen($word) <= 2) 
                continue;

            $query .= "((mypm1.meta_key = 'speel')";
            $query .= " AND (mypm1.meta_value  LIKE '%{$word}%')) OR ";
        }

        if (!empty($query)) {
            // add to where clause
            $pieces['where'] = str_replace("(((wp_posts.post_title LIKE '%", "( {$query} ((wp_posts.post_title LIKE '%", $pieces['where']);

            $pieces['join'] = $pieces['join'] . " INNER JOIN {$wpdb->postmeta} AS mypm1 ON ({$wpdb->posts}.ID = mypm1.post_id)";
        }
    }
    return ($pieces);
}
add_filter('posts_clauses', 'custom_search_where', 20, 1);

2

আমার একই সমস্যা ছিল, আমার নতুন সাইটের জন্য আমি কেবল একটি নতুন মেটা "শিরোনাম" যুক্ত করেছি:

থিমের functions.php

add_action('save_post', 'title_to_meta');

function title_to_meta($post_id)
{
    update_post_meta($post_id, 'title', get_the_title($post_id)); 
}

এবং তারপরে .. ঠিক এর মতো কিছু যুক্ত করুন:

$sub = array('relation' => 'OR');

$sub[] = array(
    'key'     => 'tags',
    'value'   => $_POST['q'],
    'compare' => 'LIKE',
);

$sub[] = array(
    'key'     => 'description',
    'value'   => $_POST['q'],
    'compare' => 'LIKE',
);

$sub[] = array(
    'key'     => 'title',
    'value'   => $_POST['q'],
    'compare' => 'LIKE',
);

$params['meta_query'] = $sub;

আপনি এই কর্মসংস্থান সম্পর্কে কি মনে করেন?


1
এটি আসলে খারাপ নয়, তবে আপনার প্রয়োজন হয় বিদ্যমান বিদ্যমান পোস্টগুলি পুনরায় সংরক্ষণ করুন বা আপনি সামগ্রী যুক্ত করা শুরু করার আগে এটি ব্যবহার শুরু করুন।
বেরেন্ড

@ বেরেন্ড আপনি সম্ভবত এমন একটি ফাংশন লিখতে পারেন যা সমস্ত পোস্ট এবং প্রতিটিটির জন্য পোস্ট_মেটা আপডেট করার মাধ্যমে লুপ করে। এটি কোনও কাস্টম টেম্পলেট বা ফাংশনে অন্তর্ভুক্ত করুন, এটি একবার চালান, তারপরে এটি বাতিল করুন।
স্ল্যাম

1

উপরের সমস্ত সমাধানগুলি কেবল তখনই ফলাফলগুলি প্রত্যাবর্তন করে যদি বানান মেটা কীতে কোনও মিল থাকে। আপনার যদি অন্য কোথাও ফলাফল হয় তবে এই ক্ষেত্রে না থেকে আপনি কিছুই পাবেন না। কেউ তা চায় না।

একটি বাম জোড় প্রয়োজন। নিম্নলিখিত একটি তৈরি করবে।

           $meta_query_args = array(
              'relation' => 'OR',
              array(
                'key' => 'speel',
                'value' => $search_term,
                'compare' => 'LIKE',
              ),
              array(
                'key' => 'speel',
                'compare' => 'NOT EXISTS',
              ),
            );
            $query->set('meta_query', $meta_query_args);

0

এটি দুর্দান্ত সমাধান তবে আপনাকে একটি জিনিস ঠিক করতে হবে। আপনি যখন 'post__in' কল করেন আপনাকে আইডির একটি অ্যারে সেট করতে হবে এবং পোস্টের একটি অ্যারে $ অনন্য।

উদাহরণ:

$q1 = get_posts(array(
        'fields' => 'ids',
        'post_type' => 'post',
        's' => $query
));

$q2 = get_posts(array(
        'fields' => 'ids',
        'post_type' => 'post',
        'meta_query' => array(
            array(
               'key' => 'speel',
               'value' => $query,
               'compare' => 'LIKE'
            )
         )
));

$unique = array_unique( array_merge( $q1->posts, $q2->posts ) );

$array = array(); //here you initialize your array

foreach($posts as $post)
{
    $array[] = $post->ID; //fill the array with post ID
}


$posts = get_posts(array(
    'post_type' => 'posts',
    'post__in' => $array,
    'post_status' => 'publish',
    'posts_per_page' => -1
));

0

@ সাতবীর-কীরা উত্তরটি দুর্দান্ত কাজ করে তবে এটি কেবল মেটা এবং পোস্ট শিরোনামের মাধ্যমে অনুসন্ধান করবে। আপনি যদি এটি মেটা, শিরোনাম এবং সামগ্রীর মাধ্যমে অনুসন্ধান করতে চান তবে পরিবর্তিত সংস্করণ এখানে।

    add_action( 'pre_get_posts', function( $q )
    {
      if( $title = $q->get( '_meta_or_title' ) )
      {
        add_filter( 'get_meta_sql', function( $sql ) use ( $title )
        {
          global $wpdb;

          // Only run once:
          static $nr = 0;
          if( 0 != $nr++ ) return $sql;

          // Modified WHERE
          $sql['where'] = sprintf(
              " AND ( (%s OR %s) OR %s ) ",
              $wpdb->prepare( "{$wpdb->posts}.post_title like '%%%s%%'", $title),
              $wpdb->prepare( "{$wpdb->posts}.post_content like '%%%s%%'", $title),
              mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
          );

          return $sql;
        });
      }
    });

এবং এখানে এটি ব্যবহার:

$args['_meta_or_title'] = $get['search']; //not using 's' anymore

$args['meta_query'] = array(
  'relation' => 'OR',
  array(
    'key' => '_ltc_org_name',
    'value' => $get['search'],
    'compare' => 'LIKE'
  ),
  array(
    'key' => '_ltc_org_school',
    'value' => $get['search'],
    'compare' => 'LIKE'
  ),
  array(
    'key' => '_ltc_district_address',
    'value' => $get['search'],
    'compare' => 'LIKE'
  )
);

$get['search']আপনার অনুসন্ধান মান দিয়ে প্রতিস্থাপন করুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.