Skip to content

Instantly share code, notes, and snippets.

@dfeyer
Last active December 16, 2015 19:48
Show Gist options
  • Save dfeyer/5487256 to your computer and use it in GitHub Desktop.
Save dfeyer/5487256 to your computer and use it in GitHub Desktop.
TYPO3.ElasticSearch Query API proposal
<?php
namespace Ttree\Medialib\Core\Domain\Repository\ElasticSearch;
/* *
* This script belongs to the FLOW3 package "Ttree.Medialib". *
* *
* */
use TYPO3\Flow\Annotations as Flow;
/**
* A repository for Movies
*
* @Flow\Scope("singleton")
* @method findByProductionYear
*/
class MovieRepository extends \TYPO3\ElasticSearch\Persistence\Repository {
const ENTITY_CLASSNAME = 'Ttree\Medialib\Core\Domain\Model\Movie';
/**
* @Flow\Inject
* @var \TYPO3\Flow\Security\Context
*/
protected $securityContext;
/**
* Returns a query for objects of this repository
*
* @return \TYPO3\ElasticSearch\Persistence\Query
* @api
*/
public function createQuery() {
$query = parent::createQuery();
$query->setOrderings(array(
'public' => \TYPO3\Flow\Persistence\QueryInterface::ORDER_ASCENDING
))->filter(
$query->logicalAnd(
$query->logicalAnd(
$query->logicalOr(
$query->createTermQuery($query->equals('owner', (string)$this->securityContext->getDomain())),
$query->createTermQuery($query->equals('owner', 'production.'.(string)$this->securityContext->getDomain()))
),
$query->createTermQuery($query->equals('productionYear', 2004))
),
$query->logicalAnd(
$query->createTermQuery($query->equals('owner', (string)$this->securityContext->getDomain())),
$query->createTermQuery($query->equals('productionYear', 2004))
)
)
);
return $query;
}
/**
* @param string $title
* @return \TYPO3\Flow\Persistence\QueryResultInterface
*/
public function findByTitleWithSimpleQuery($title) {
$query = $this->createQuery();
$query->matching($query->equals('title', $title));
return $query->execute();
}
/**
* @param string $title
* @return \TYPO3\Flow\Persistence\QueryResultInterface
*/
public function findByTitleAndDescriptionWithMultiMatchQuery($title) {
$query = $this->createQuery();
$query->matching($query->createMultiMatchPhraseQuery(array('title.technicalLocalTitle', 'description'), $title));
return $query->execute();
}
/**
* @param string $title
* @return \TYPO3\Flow\Persistence\QueryResultInterface
*/
public function findByTitleWithBooleanQuery($title) {
$query = $this->createQuery();
$query->matching(
$query->createBooleanQuery()
->must(
$query->createMatchPhrasePrefixQuery(
$query->equals('title.technicalLocalTitle', $title)
)
)->should(
$query->createTermQuery(
$query->equals('title.technicalLocalTitle', 'Claude')
)->setBoost(2.0)
)->mustNot(
$query->createMatchQuery(
$query->equals('title.technicalLocalTitle', 'Closky')
)
)
);
return $query->execute();
}
/**
* @return \TYPO3\Flow\Persistence\QueryResultInterface
*/
public function findByTitleWithBoostingQuery() {
$query = $this->createQuery();
$query->matching(
$query->createBoostingQuery()
->positive(
$query->createMatchPhraseQuery(
$query->equals('title.technicalLocalTitle', 'Claude')
)->setOperator('and')
)->negative(
$query->createMatchQuery(
$query->equals('title.technicalLocalTitle', 'David')
)->setOperator('and')
)->negativeBoost(0.2)
);
return $query->execute();
}
/**
* @return \TYPO3\Flow\Persistence\QueryResultInterface
*/
public function findByTitleWithBoostingAndAdvancedPhraseQuery() {
$query = $this->createQuery();
$query->matching(
$query->createBoostingQuery()
->positive(
$query->createMatchPhraseQuery(
$query->equals('title.technicalLocalTitle', 'Claude')
)->setOperator('and')
)->negative(
$query->createMatchPhrasePrefixQuery(
$query->equals('title.technicalLocalTitle', 'David')
)->setOperator('and')->setMaxExpansions(10)
)->negativeBoost(0.2)
);
return $query->execute();
}
}
?>
@dfeyer
Copy link
Author

dfeyer commented Apr 30, 2013

Currenty support this query type: match, match_phrase, term, and + bool

Bool query, see http://www.elasticsearch.org/guide/reference/query-dsl/bool-query/, can have three contraints (must, should and must_not), so he can be use has a "logicalNot" replacement currently.

Currently "logicalAnd" can only be used in filter and not in query, bool must be used in this case. No clear idea how to validate this in Flow ... or if we need to validate this at all ;)

@afoeder
Copy link

afoeder commented Apr 30, 2013

do the arguments of $query->bool() represent the three constraints, so, do we have ->bool($must=NULL, $should=NULL, $mustNot=NULL)? Although that's rather straight forward, what do you think about a BooleanQueryConstraint with the appropriate methods?
Like,

<?php
$boolean = $query->createBooleanQuery();
$boolean->must(...);
$boolean->should...
$query->matching($boolean);

If no binding to the "parent" query is necessary, the BooleanQueryConstraint could also be instantiated via new.

I'm just worried about the fact that, as of http://www.elasticsearch.org/guide/reference/query-dsl/bool-query/, the three constraints do not have any predictable order.

@afoeder
Copy link

afoeder commented Apr 30, 2013

an additional thing; I could think the "Repository" terminology is subject to be confused with Flow's "real" persistence repositories, in particular regarding also the const ENTITY_CLASSNAME etc...
But still, Repository is the correct naming ofc...
Is the \TYPO3\ElasticSearch\Persistence\Repository related to Flow's Repository in any regards? Does it extend it?

@dfeyer
Copy link
Author

dfeyer commented Apr 30, 2013

I agree with the createBooleanQuery() and API proposal, sounds good

About the Repository, I hope to found a solution to have real repository, with update / add method using doctring and all find query based on ElasticSearch, so this is a full repository ;)

@dfeyer
Copy link
Author

dfeyer commented Apr 30, 2013

The patchset on Gerrit is updated with the last modification: https://review.typo3.org/#/c/20167/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment