mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2025-01-31 11:16:42 +01:00
#1: Implemented Elasticsearch mappings for playlists and users.
This commit is contained in:
parent
a5bb117ae7
commit
dbbaa03542
9 changed files with 82 additions and 31 deletions
|
@ -54,6 +54,7 @@ class AddTrackToPlaylistCommand extends CommandBase
|
||||||
{
|
{
|
||||||
$songIndex = $this->_playlist->tracks()->count() + 1;
|
$songIndex = $this->_playlist->tracks()->count() + 1;
|
||||||
$this->_playlist->tracks()->attach($this->_track, ['position' => $songIndex]);
|
$this->_playlist->tracks()->attach($this->_track, ['position' => $songIndex]);
|
||||||
|
$this->_playlist->touch();
|
||||||
|
|
||||||
Playlist::whereId($this->_playlist->id)->update([
|
Playlist::whereId($this->_playlist->id)->update([
|
||||||
'track_count' => DB::raw('(SELECT COUNT(id) FROM playlist_track WHERE playlist_id = ' . $this->_playlist->id . ')')
|
'track_count' => DB::raw('(SELECT COUNT(id) FROM playlist_track WHERE playlist_id = ' . $this->_playlist->id . ')')
|
||||||
|
|
|
@ -79,15 +79,18 @@ class RebuildSearchIndex extends Command
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Playlist::withTrashed()->chunk(200, function(Collection $playlists) {
|
Playlist::withTrashed()->chunk(200, function(Collection $playlists) {
|
||||||
// foreach($playlists as $playlist) {
|
foreach($playlists as $playlist) {
|
||||||
// $this->info("Processing playlist #{$playlist->id}...");
|
$this->info("Processing playlist #{$playlist->id}...");
|
||||||
// $playlist->ensureElasticsearchEntryIsUpToDate();
|
$playlist->ensureElasticsearchEntryIsUpToDate();
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
//
|
|
||||||
// User::withTrashed()->chunk(200, function(User $user) {
|
User::chunk(200, function(Collection $users) {
|
||||||
// $user->ensureElasticsearchEntryIsUpToDate();
|
foreach($users as $user) {
|
||||||
// });
|
$this->info("Processing user #{$user->id}...");
|
||||||
|
$user->ensureElasticsearchEntryIsUpToDate();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace Poniverse\Ponyfm\Library;
|
||||||
|
|
||||||
use DB;
|
use DB;
|
||||||
use Elasticsearch\Client;
|
use Elasticsearch\Client;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Poniverse\Ponyfm\Models\Album;
|
use Poniverse\Ponyfm\Models\Album;
|
||||||
use Poniverse\Ponyfm\Models\Playlist;
|
use Poniverse\Ponyfm\Models\Playlist;
|
||||||
|
@ -53,11 +54,11 @@ class Search {
|
||||||
'multi_match' => [
|
'multi_match' => [
|
||||||
'query' => $query,
|
'query' => $query,
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'title',
|
'title^3',
|
||||||
'artist',
|
'artist^2',
|
||||||
'genre',
|
'genre',
|
||||||
'track_type',
|
'track_type',
|
||||||
'show_songs',
|
'show_songs^2',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
@ -71,7 +72,7 @@ class Search {
|
||||||
'multi_match' => [
|
'multi_match' => [
|
||||||
'query' => $query,
|
'query' => $query,
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'title',
|
'title^2',
|
||||||
'artist',
|
'artist',
|
||||||
'tracks',
|
'tracks',
|
||||||
],
|
],
|
||||||
|
@ -87,8 +88,9 @@ class Search {
|
||||||
'multi_match' => [
|
'multi_match' => [
|
||||||
'query' => $query,
|
'query' => $query,
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'title',
|
'title^3',
|
||||||
'user',
|
'curator',
|
||||||
|
'tracks^2',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
@ -102,7 +104,8 @@ class Search {
|
||||||
'multi_match' => [
|
'multi_match' => [
|
||||||
'query' => $query,
|
'query' => $query,
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'display_name',
|
'display_name^2',
|
||||||
|
'tracks',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
@ -150,7 +153,14 @@ class Search {
|
||||||
}
|
}
|
||||||
$caseStatement .= 'END';
|
$caseStatement .= 'END';
|
||||||
|
|
||||||
$modelInstances = $modelClass::withTrashed()
|
/** @var Builder $modelInstances */
|
||||||
|
$modelInstances = $modelClass::query();
|
||||||
|
|
||||||
|
if (method_exists($modelClass, 'withTrashed')) {
|
||||||
|
$modelInstances = $modelInstances->withTrashed();
|
||||||
|
}
|
||||||
|
|
||||||
|
$modelInstances = $modelInstances
|
||||||
->whereIn('id', array_keys($ids))
|
->whereIn('id', array_keys($ids))
|
||||||
->orderBy(DB::raw($caseStatement))
|
->orderBy(DB::raw($caseStatement))
|
||||||
->get();
|
->get();
|
||||||
|
|
|
@ -28,7 +28,7 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
use Auth;
|
use Auth;
|
||||||
use Cache;
|
use Cache;
|
||||||
use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException;
|
use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException;
|
||||||
use Poniverse\Ponyfm\Traits\IndexedInElasticsearch;
|
use Poniverse\Ponyfm\Traits\IndexedInElasticsearchTrait;
|
||||||
use Poniverse\Ponyfm\Traits\TrackCollection;
|
use Poniverse\Ponyfm\Traits\TrackCollection;
|
||||||
use Poniverse\Ponyfm\Traits\SlugTrait;
|
use Poniverse\Ponyfm\Traits\SlugTrait;
|
||||||
use Venturecraft\Revisionable\RevisionableTrait;
|
use Venturecraft\Revisionable\RevisionableTrait;
|
||||||
|
@ -62,7 +62,7 @@ use Venturecraft\Revisionable\RevisionableTrait;
|
||||||
*/
|
*/
|
||||||
class Album extends Model
|
class Album extends Model
|
||||||
{
|
{
|
||||||
use SoftDeletes, SlugTrait, DispatchesJobs, TrackCollection, RevisionableTrait, IndexedInElasticsearch;
|
use SoftDeletes, SlugTrait, DispatchesJobs, TrackCollection, RevisionableTrait, IndexedInElasticsearchTrait;
|
||||||
|
|
||||||
protected $elasticsearchType = 'album';
|
protected $elasticsearchType = 'album';
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
use Auth;
|
use Auth;
|
||||||
use Cache;
|
use Cache;
|
||||||
use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException;
|
use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException;
|
||||||
use Poniverse\Ponyfm\Traits\IndexedInElasticsearch;
|
use Poniverse\Ponyfm\Traits\IndexedInElasticsearchTrait;
|
||||||
use Poniverse\Ponyfm\Traits\TrackCollection;
|
use Poniverse\Ponyfm\Traits\TrackCollection;
|
||||||
use Poniverse\Ponyfm\Traits\SlugTrait;
|
use Poniverse\Ponyfm\Traits\SlugTrait;
|
||||||
use Venturecraft\Revisionable\RevisionableTrait;
|
use Venturecraft\Revisionable\RevisionableTrait;
|
||||||
|
@ -61,7 +61,7 @@ use Venturecraft\Revisionable\RevisionableTrait;
|
||||||
*/
|
*/
|
||||||
class Playlist extends Model
|
class Playlist extends Model
|
||||||
{
|
{
|
||||||
use SoftDeletes, SlugTrait, DispatchesJobs, TrackCollection, RevisionableTrait, IndexedInElasticsearch;
|
use SoftDeletes, SlugTrait, DispatchesJobs, TrackCollection, RevisionableTrait, IndexedInElasticsearchTrait;
|
||||||
|
|
||||||
protected $elasticsearchType = 'playlist';
|
protected $elasticsearchType = 'playlist';
|
||||||
|
|
||||||
|
@ -295,6 +295,10 @@ class Playlist extends Model
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function toElasticsearch() {
|
public function toElasticsearch() {
|
||||||
return $this->toArray();
|
return [
|
||||||
|
'title' => $this->title,
|
||||||
|
'curator' => $this->user->display_name,
|
||||||
|
'tracks' => $this->tracks->pluck('title'),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ use Config;
|
||||||
use DB;
|
use DB;
|
||||||
use Elasticsearch;
|
use Elasticsearch;
|
||||||
use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException;
|
use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException;
|
||||||
use Poniverse\Ponyfm\Traits\IndexedInElasticsearch;
|
use Poniverse\Ponyfm\Traits\IndexedInElasticsearchTrait;
|
||||||
use Poniverse\Ponyfm\Traits\SlugTrait;
|
use Poniverse\Ponyfm\Traits\SlugTrait;
|
||||||
use Exception;
|
use Exception;
|
||||||
use External;
|
use External;
|
||||||
|
@ -97,7 +97,7 @@ use Venturecraft\Revisionable\RevisionableTrait;
|
||||||
*/
|
*/
|
||||||
class Track extends Model
|
class Track extends Model
|
||||||
{
|
{
|
||||||
use SoftDeletes, IndexedInElasticsearch;
|
use SoftDeletes, IndexedInElasticsearchTrait;
|
||||||
|
|
||||||
protected $elasticsearchType = 'track';
|
protected $elasticsearchType = 'track';
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Foundation\Auth\Access\Authorizable;
|
use Illuminate\Foundation\Auth\Access\Authorizable;
|
||||||
use Auth;
|
use Auth;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Poniverse\Ponyfm\Traits\IndexedInElasticsearch;
|
use Poniverse\Ponyfm\Traits\IndexedInElasticsearchTrait;
|
||||||
use Venturecraft\Revisionable\RevisionableTrait;
|
use Venturecraft\Revisionable\RevisionableTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,7 +65,7 @@ use Venturecraft\Revisionable\RevisionableTrait;
|
||||||
*/
|
*/
|
||||||
class User extends Model implements AuthenticatableContract, CanResetPasswordContract, \Illuminate\Contracts\Auth\Access\Authorizable
|
class User extends Model implements AuthenticatableContract, CanResetPasswordContract, \Illuminate\Contracts\Auth\Access\Authorizable
|
||||||
{
|
{
|
||||||
use Authenticatable, CanResetPassword, Authorizable, RevisionableTrait, IndexedInElasticsearch;
|
use Authenticatable, CanResetPassword, Authorizable, RevisionableTrait, IndexedInElasticsearchTrait;
|
||||||
|
|
||||||
protected $elasticsearchType = 'user';
|
protected $elasticsearchType = 'user';
|
||||||
|
|
||||||
|
@ -258,6 +258,10 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function toElasticsearch() {
|
public function toElasticsearch() {
|
||||||
return $this->toArray();
|
return [
|
||||||
|
'username' => $this->username,
|
||||||
|
'display_name' => $this->display_name,
|
||||||
|
'tracks' => $this->tracks->pluck('title'),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ use Elasticsearch;
|
||||||
*
|
*
|
||||||
* @package Poniverse\Ponyfm\Traits
|
* @package Poniverse\Ponyfm\Traits
|
||||||
*/
|
*/
|
||||||
trait IndexedInElasticsearch
|
trait IndexedInElasticsearchTrait
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Returns this model in Elasticsearch-friendly form. The array returned by
|
* Returns this model in Elasticsearch-friendly form. The array returned by
|
||||||
|
@ -83,7 +83,7 @@ trait IndexedInElasticsearch
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ensureElasticsearchEntryIsUpToDate() {
|
public function ensureElasticsearchEntryIsUpToDate() {
|
||||||
if ($this->trashed()) {
|
if (method_exists($this, 'trashed') && $this->trashed()) {
|
||||||
$this->deleteElasticsearchEntry();
|
$this->deleteElasticsearchEntry();
|
||||||
} else {
|
} else {
|
||||||
$this->createOrUpdateElasticsearchEntry();
|
$this->createOrUpdateElasticsearchEntry();
|
|
@ -42,6 +42,7 @@ class SetupElasticsearch extends Migration
|
||||||
'properties' => [
|
'properties' => [
|
||||||
'title' => ['type' => 'string'],
|
'title' => ['type' => 'string'],
|
||||||
'artist' => ['type' => 'string', 'index' => 'not_analyzed'],
|
'artist' => ['type' => 'string', 'index' => 'not_analyzed'],
|
||||||
|
|
||||||
'published_at' => ['type' => 'date'],
|
'published_at' => ['type' => 'date'],
|
||||||
'genre' => ['type' => 'string', 'index' => 'not_analyzed'],
|
'genre' => ['type' => 'string', 'index' => 'not_analyzed'],
|
||||||
'track_type' => ['type' => 'string', 'index' => 'not_analyzed'],
|
'track_type' => ['type' => 'string', 'index' => 'not_analyzed'],
|
||||||
|
@ -65,7 +66,35 @@ class SetupElasticsearch extends Migration
|
||||||
// See: https://www.elastic.co/guide/en/elasticsearch/reference/current/array.html
|
// See: https://www.elastic.co/guide/en/elasticsearch/reference/current/array.html
|
||||||
'tracks' => ['type' => 'string']
|
'tracks' => ['type' => 'string']
|
||||||
]
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
'playlist' => [
|
||||||
|
'_source' => ['enabled' => true],
|
||||||
|
'dynamic' => 'strict',
|
||||||
|
'properties' => [
|
||||||
|
'title' => ['type' => 'string'],
|
||||||
|
'curator' => ['type' => 'string', 'index' => 'not_analyzed'],
|
||||||
|
|
||||||
|
// This field is intended to be used as an array.
|
||||||
|
// Note that all Elasticsearch fields can technically be used as arrays.
|
||||||
|
// See: https://www.elastic.co/guide/en/elasticsearch/reference/current/array.html
|
||||||
|
'tracks' => ['type' => 'string']
|
||||||
]
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
'user' => [
|
||||||
|
'_source' => ['enabled' => true],
|
||||||
|
'dynamic' => 'strict',
|
||||||
|
'properties' => [
|
||||||
|
'username' => ['type' => 'string', 'index' => 'not_analyzed'],
|
||||||
|
'display_name' => ['type' => 'string', 'index' => 'not_analyzed'],
|
||||||
|
|
||||||
|
// This field is intended to be used as an array.
|
||||||
|
// Note that all Elasticsearch fields can technically be used as arrays.
|
||||||
|
// See: https://www.elastic.co/guide/en/elasticsearch/reference/current/array.html
|
||||||
|
'tracks' => ['type' => 'string']
|
||||||
|
]
|
||||||
|
],
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
|
|
Loading…
Reference in a new issue