public static function searchES(array $params = []) { extract($params); $count = config('osu.beatmaps.max', 50); $offset = max(0, $page - 1) * $count; $current_user = Auth::user(); $searchParams['index'] = config('osu.elasticsearch.index'); $searchParams['type'] = 'beatmaps'; $searchParams['size'] = $count; $searchParams['from'] = $offset; $searchParams['body']['sort'] = [$sort_field => ['order' => $sort_order]]; $searchParams['fields'] = ['id']; $matchParams = []; $shouldParams = []; if (presence($genre) !== null) { $matchParams[] = ['match' => ['genre_id' => (int) $genre]]; } if (presence($language) !== null) { $matchParams[] = ['match' => ['language_id' => (int) $language]]; } if (is_array($extra) && !empty($extra)) { foreach ($extra as $val) { switch ($val) { case 0: // video $matchParams[] = ['match' => ['video' => 1]]; break; case 1: // storyboard $matchParams[] = ['match' => ['storyboard' => 1]]; break; } } } if (presence($query) !== null) { $matchParams[] = ['query_string' => ['query' => $query]]; } if (!empty($rank)) { $klass = presence($mode) !== null ? Score\Best\Model::getClass(intval($mode)) : Score\Best\Combined::class; $scores = model_pluck($klass::forUser($current_user)->whereIn('rank', $rank), 'beatmapset_id'); $matchParams[] = ['ids' => ['type' => 'beatmaps', 'values' => $scores]]; } // TODO: This logic probably shouldn't be at the model level... maybe? if (presence($status) !== null) { switch ((int) $status) { case 0: // Ranked & Approved $shouldParams[] = [['match' => ['approved' => self::STATES['ranked']]], ['match' => ['approved' => self::STATES['approved']]]]; break; case 1: // Approved $matchParams[] = ['match' => ['approved' => self::STATES['approved']]]; break; case 2: // Favourites $favs = model_pluck($current_user->favouriteBeatmapsets(), 'beatmapset_id'); $matchParams[] = ['ids' => ['type' => 'beatmaps', 'values' => $favs]]; break; case 3: // Mod Requests $maps = model_pluck(ModQueue::select(), 'beatmapset_id'); $matchParams[] = ['ids' => ['type' => 'beatmaps', 'values' => $maps]]; $matchParams[] = ['match' => ['approved' => self::STATES['pending']]]; break; case 4: // Pending $shouldParams[] = [['match' => ['approved' => self::STATES['wip']]], ['match' => ['approved' => self::STATES['pending']]]]; break; case 5: // Graveyard $matchParams[] = ['match' => ['approved' => self::STATES['graveyard']]]; break; case 6: // My Maps $maps = model_pluck($current_user->beatmapsets(), 'beatmapset_id'); $matchParams[] = ['ids' => ['type' => 'beatmaps', 'values' => $maps]]; break; case 7: // Explicit Any break; default: // null, etc break; } } else { $matchParams[] = ['range' => ['approved' => ['gte' => self::STATES['pending']]]]; } if (presence($mode) !== null) { $matchParams[] = ['match' => ['playmode' => (int) $mode]]; } if (!empty($matchParams)) { $searchParams['body']['query']['bool']['must'] = $matchParams; } if (!empty($shouldParams)) { $searchParams['body']['query']['bool']['should'] = $shouldParams; $searchParams['body']['query']['bool']['minimum_should_match'] = 1; } try { $results = Es::search($searchParams); $beatmap_ids = array_map(function ($e) { return $e['_id']; }, $results['hits']['hits']); } catch (\Exception $e) { $beatmap_ids = []; } return $beatmap_ids; }