最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - How to filter the output of the data received from the database based on the meta relation? - Stack Overflow

programmeradmin10浏览0评论

I want to filter the output of the data I receive from the database based on the meta relation. The output looks like this:

  #primaryKey: "ID"
  #keyType: "int"
  +incrementing: true
  #with: array:1 [▶]
  #withCount: []
  +preventsLazyLoading: false
  #perPage: 15
  +exists: true
  +wasRecentlyCreated: false
  #escapeWhenCastingToString: false
  #attributes: array:23 [▶]
  ...
  #relations: array:1 [▼
    "meta" => \MetaCollection {#2861 ▼
      #items: array:58 [▼
        0 => \PostMeta {#3604 ▼
          ..
          #attributes: array:4 [▼
            "meta_id" => 892
            "post_id" => 253
            "meta_key" => "_manage_stock"
            "meta_value" => "yes"
          ]
          ...
        }

Inside the meta relation, I only want to have the item where the meta_key is equal to _manage_stock. The code I wrote does not work correctly and doesn't apply any filters to it.

$metaKey = '_manage_stock';

$filteredProducts = Product::all()
    ->filter(function ($product) use ($metaKey) {
        return $product->meta->contains(function ($meta) use ($metaKey) {
            return $meta->meta_key === $metaKey;
        });
    });

This structure and data are related to WordPress, and for some reasons, I cannot use whereHas. How can I extract meta_key values from the meta relationship where the value is equal to _manage_stock?

I want to filter the output of the data I receive from the database based on the meta relation. The output looks like this:

  #primaryKey: "ID"
  #keyType: "int"
  +incrementing: true
  #with: array:1 [▶]
  #withCount: []
  +preventsLazyLoading: false
  #perPage: 15
  +exists: true
  +wasRecentlyCreated: false
  #escapeWhenCastingToString: false
  #attributes: array:23 [▶]
  ...
  #relations: array:1 [▼
    "meta" => \MetaCollection {#2861 ▼
      #items: array:58 [▼
        0 => \PostMeta {#3604 ▼
          ..
          #attributes: array:4 [▼
            "meta_id" => 892
            "post_id" => 253
            "meta_key" => "_manage_stock"
            "meta_value" => "yes"
          ]
          ...
        }

Inside the meta relation, I only want to have the item where the meta_key is equal to _manage_stock. The code I wrote does not work correctly and doesn't apply any filters to it.

$metaKey = '_manage_stock';

$filteredProducts = Product::all()
    ->filter(function ($product) use ($metaKey) {
        return $product->meta->contains(function ($meta) use ($metaKey) {
            return $meta->meta_key === $metaKey;
        });
    });

This structure and data are related to WordPress, and for some reasons, I cannot use whereHas. How can I extract meta_key values from the meta relationship where the value is equal to _manage_stock?

Share Improve this question edited Feb 5 at 7:02 DolDurma asked Feb 5 at 6:30 DolDurmaDolDurma 17.3k56 gold badges221 silver badges422 bronze badges 1
  • please provide the current query you are using to get the first result, and how do you want to result to change exactly with an example – kris gjika Commented Feb 5 at 9:49
Add a comment  | 

3 Answers 3

Reset to default 0

If you want to filter at the query level, use whereHas() to apply the condition directly to the database query.

$metaKey = '_manage_stock';

$filteredProducts = Product::whereHas('meta', function ($query) use ($metaKey) {
    $query->where('meta_key', $metaKey);
})->get();

Instead of using all(), which loads all products first and then filters them in PHP (bad for performance), we should use whereHas() to apply the filter in SQL directly.

Performance:

  • all()->filter() loads all records and filters them in PHP (slow).
  • whereHas() filters directly in SQL

Correct way:

$metaKey = '_manage_stock';

$filteredProducts = Product::whereHas('meta', function ($query) use ($metaKey) {
    $query->where('meta_key', $metaKey);
})->get();

Try this way want to add model file with relationship function:

Ensure that $product->meta returns a collection of meta data objects. If this is a relationship, then you need to make sure it's correctly eager loaded or set up as a collection. If the meta data is a HasMany relationship (like a meta relationship in WordPress for products), then ensure it's properly loaded before using this filter. You can eager load meta if needed.

 public function meta()
    {
        return $this->hasMany(Meta::class); // or belongsToMany if necessary
    }


    $filteredProducts = Product::with('meta') // Eager load the meta relationship
        ->get()
        ->filter(function ($product) use ($metaKey) {
            return $product->meta->contains(function ($meta) use ($metaKey) {
                return $meta->meta_key === $metaKey;
            });
        });
发布评论

评论列表(0)

  1. 暂无评论