I haven't tested it but it should give you a pretty good idea on how to set this up. public function actionTest() { $entryQuery = Entry::find()->section('mySection'); // All the element relations. For example tags and categories. // These have to be Element objects. For example craft\elements\Tag. $myArrayWithTags = [/* ... */]; $myArrayWithCategories = [/* ... */]; $allRelations = array_merge($myArrayWithTags, $myArrayWithCategories); // Filter by relations $this->_applyRelationFilter($entryQuery, $allRelations); // Filter by custom fields $this->_applyFieldFilter($entryQuery, 'myRadioField', 'value2'); $this->_applyFieldFilter($entryQuery, 'myNumberField', 3); $this->_applyFieldFilter($entryQuery, 'myCheckboxField', ['option1', 'option2']); // Build response string $content = "Entries:<br>"; $content .= "<pre>" . json_encode($entryQuery->all()) . "</pre>"; // Respond $response = Craft::$app->getResponse(); $response->content = $content; return $response; } private function _applyRelationFilter(ElementQuery $query, array $elements) : array { $relatedTo = []; // Build the list of relations in the correct format foreach($elements as $element) { array_push($relatedTo, [ "targetElement" => $element ]); } // Create an array with and as the first value so // the result only contains elements that have all the set relations $relatedTo = array_merge(['and'], $relatedTo); // Set query relatedTo return $query->relatedTo($relatedTo); } private function _applyFieldFilter(ElementQuery $query, string $handle, $value) { $query->andWhere([ ('content.field_' . $handle) => $value ]); } You need to have the following imports: use Craft; use craft\elements\Entry; use craft\elements\db\ElementQuery; Info about querying by custom field: https://craftcms.stackexchange.com/a/22995/9754