I'm looking to build a list of tags in my blogging application? I want to select all tags, and if that tag exists more than once, only select it once?
This is how I get all tags! How do I get each tag only once?
$tags = Tag::all();
I'm looking to build a list of tags in my blogging application? I want to select all tags, and if that tag exists more than once, only select it once?
This is how I get all tags! How do I get each tag only once?
$tags = Tag::all();
Queries
If you're just looking for a distinct list of the tag names, you can combine the distinct()
method and the pluck()
method:
$tags = Tag::distinct()->pluck('name');
This will give you a Collection of all of the unique tag names in your system.
If you actually need to have the Tag model instances, you can try two things.
First, if you have completely duplicate tag rows, you can just add distinct()
to your tag query (since you need to modify the query, you'll need to change from using all()
to get()
(read more here):
$tags = Tag::distinct()->get();
Second, if your tags have other non distinct information (ids, timestamps, etc), that won't work. If that's the case, you'll need to use a subquery to select the tags you want:
$tags = Tag::whereIn('id', Tag::groupBy('name')->selectRaw('MAX(id)'))->get();
That will give you fully populated Tag model instances for your unique set of names.
Collections
Finally, if you already have a collection of Tag instances, and you wanted to get a unique set based on the name, you can use the unique
method on the collection.
// somewhere
$tags = Tag::get();
// somewhere else
$tags = $tags->unique('name');
If you don't already have the collection, make sure to use one of the query builder methods above. If you use the collection method, you have to build and hydrate all the Tag model instances first, and then do the unique processing. You don't want to fetch and hydrate 10000 Tag model instances to end up with 30 unique Tags in the end, when you could fetch just those 30 from the database in the first place.
You can use the unique()
method on the collection, i.e.:
$tags = Tag::all()->unique('name');
Use your descriptor field instead of name
.
The distinct()
method is better used with a limited selection of fields, like:
DB::table('tags')->distinct()->get(['name']);
If you use distinct()
on the Model
like Tag::distinct()->get();
you will get all the tags because they have different ids
and timestamps
even if they have the same name or description because, in that case, the select is on all the fields.
With the model you have to limit the fields returned like this:
Tag::distinct()->get(['name']);