Recherche avec Wikitty

Wikitty permet de rechercher parmis les entités enregistrées tout en fournissant les fonctionalités de pagination. Pour cela vous pouvez construire programmatiquement vos recherches en utilisant WikittyQueryMaker ou de façon textuelle en utilisant WikittyQueryParser.

Au final, vous obtenez dans les deux cas un WikittyQuery utilisable pour vos recherche par les méthodes WikittyClient.findXXXX.

Utilisation via WikittyClient

Les requêtes peuvent être utilisée dans les méthodes:

  • findAllByQuery(Query): WikittyQueryResult<String>

  • findByQuery(Query): String

  • findAllByQuery(Class<E>, Query): WikittyQueryResult<E>

  • findByQuery(Class<E>, Query): E

Dans les deux premières méthodes les résultats seront retournés de façon brute sous forme de String. Si le résultat représente une entité, le String sera son id. Si le résultat représente une Date, la date sera la valeur tel que retournée par la méthode WikittyUtil.toString(Date)

Les deux dernières méthodes essaient de convertir le résultat en objet de la classe passée en paramètre. Par exemple si vous savez que les résultats sont des valeurs numeriques vous pouvez passer Number.class en argument.

Vous pouvez aussi utiliser les méthodes suivantes qui construiront les requêtes pour vous:

  • findAllByExample(E): List<E>

  • findByExample(E): E

Structure d'une requête

Par exemple si vous souhaitez faire la recherche sur:

User.lastname=poussin AND User.firstname=benjamin

Vous pouvez soit utiliser le WikittyQueryMaker:

WikittyQuery query = new WikittyQueryMaker()
.and()
.eq(User.ELEMENT_FIELD_USER_LASTNAME, "poussin")
.eq(User.ELEMENT_FIELD_USER_FIRSTNAME, "benjamin")
.end();

Le end() indique que la condition est finie et que l'on souhaite la query

Vous pouvez aussi utiliser WikittyQueryParser pour faire le même travail, mais il est plus sûr d'utiliser le WikittyQueryMaker tant que vous le pouvez:

WikittyQuery query = WikittyQueryParser.parse(
"User.lastname=poussin User.firstname=benjamin");

S'il n'y a pas d'opérateur entre deux contraintes un AND est automatiquement ajouté.

Les contraintes disponibles

De nombreuses contraintes sont disponibles pour créer vos recherches :

Egalité : eq

Vérifie si un champ est égal a une valeur, si le champs est un champs texte, il est possible d'ajouter des "*" en début et en fin de la chaîne de recherche pour faire l'équivalent d'un startsWith ou endsWith. Si vous utilisez WikittyQueryMaker les méthodes sw (startsWith) et ew (endsWith) font ce travail pour vous.:

WikittyQuery q = new WikittyQueryMaker().eq(User.ELEMENT_FIELD_USER_LASTNAME, "poussin").end();
WikittyQuery q = new WikittyQueryMaker().eq(User.ELEMENT_FIELD_USER_LASTNAME, "*ssin").end();
WikittyQuery q = new WikittyQueryMaker().ew(User.ELEMENT_FIELD_USER_LASTNAME, "ssin").end();

WikittyQuery q = WikittyQueryParser.parse("User.lastname=poussin");
WikittyQuery q = WikittyQueryParser.parse("User.lastname=*ssin");
WikittyQuery q = WikittyQueryParser.parse("User.lastname=*ssin");

Non égalité : neq

Vérifie si un champ n'est pas égal a une valeur. De la même façon que le eq, il est possible d'ajouter des '*'. Ou d'utiliser les méthode notsw et notew.:

WikittyQuery q = new WikittyQueryMaker().ne(User.ELEMENT_FIELD_USER_LASTNAME, "poussin").end();
WikittyQuery q = new WikittyQueryMaker().ne(User.ELEMENT_FIELD_USER_LASTNAME, "*ssin").end();
WikittyQuery q = new WikittyQueryMaker().notew(User.ELEMENT_FIELD_USER_LASTNAME, "ssin").end();

WikittyQuery q = WikittyQueryParser.parse("User.lastname!=poussin");
WikittyQuery q = WikittyQueryParser.parse("User.lastname!=*ssin");
WikittyQuery q = WikittyQueryParser.parse("User.lastname!=*ssin");

Egalité sans casse ni accent: eqIgnoreCaseAndAccent

Vérifie si un champ est égal a une valeur, si le champs est un champs texte, il est possible d'ajouter des "*" en début et en fin de la chaîne de recherche pour faire l'équivalent d'un startsWith ou endsWith. La recherche est faite sans tenir compte de la casse ni des accents:

WikittyQuery q = new WikittyQueryMaker().eqIgnoreCaseAndAccent(User.ELEMENT_FIELD_USER_LASTNAME, "Poussin").end();
WikittyQuery q = new WikittyQueryMaker().eqIgnoreCaseAndAccent(User.ELEMENT_FIELD_USER_LASTNAME, "*SSIN").end();

WikittyQuery q = WikittyQueryParser.parse("User.lastname~Poussin");
WikittyQuery q = WikittyQueryParser.parse("User.lastname~*SSIN");

Non égalité sans casse ni accent: neIgnoreCaseAndAccent

Vérifie si un champ n'est pas égal a une valeur. De la même façon que le eqIgnoreCaseAndAccent, il est possible d'ajouter des '*'.:

WikittyQuery q = new WikittyQueryMaker().ne(User.ELEMENT_FIELD_USER_LASTNAME, "Poussin").end();
WikittyQuery q = new WikittyQueryMaker().ne(User.ELEMENT_FIELD_USER_LASTNAME, "*SSIN").end();

WikittyQuery q = WikittyQueryParser.parse("User.lastname!~Poussin");
WikittyQuery q = WikittyQueryParser.parse("User.lastname!~*SSIN");

Contient un : containsOne

Vérifie si un champ multivalué contient au moins une valeur de la liste des valeurs passées en argument:

WikittyQuery q = new WikittyQueryMaker()
.containsOne(User.ELEMENT_FIELD_USER_LASTNAME, "poussin", "couteau").end();

WikittyQuery q = WikittyQueryParser.parse("User.lastname={poussin, couteau}");

Egalité d'extension : exteq

Vérifie si un Wikitty possède une extension:

WikittyQuery q = new WikittyQueryMaker()
.exteq(User.EXT_USER).end();

WikittyQuery q = WikittyQueryParser.parse("extension=User");

Non égalité d'extension : extne

Vérifie qu'un Wikitty ne porte pas une extension.:

WikittyQuery q = new WikittyQueryMaker()
.extne(User.EXT_USER).end();

WikittyQuery q = WikittyQueryParser.parse("extension!=User");

ContainsAll d'extension : extContainsAll

Vérifie si un Wikitty possède toutes les extensions:

WikittyQuery q = new WikittyQueryMaker()
.extContainsAll(User.EXT_USER, Employee.EXT_EMPLOYEE).end();

WikittyQuery q = WikittyQueryParser.parse("extension=[User, Employee]");

Égalité d'identifiant : ideq

Vérifie qu'un Wikitty porte l'identifiant:

WikittyQuery q = new WikittyQueryMaker()
.ideq(User.EXT_USER).end();

WikittyQuery q = WikittyQueryParser.parse("id=1234567-1234-1234567");

Non égalité d'identifiant : idneq

Vérifie qu'un Wikitty ne porte pas l'identifiant.:

WikittyQuery q = new WikittyQueryMaker()
.idne(User.EXT_USER).end();

WikittyQuery q = WikittyQueryParser.parse("id!=1234567-1234-1234567");

Similitude : like

Vérifie qu'une chaîne de caractère est égale à une autre sans tenir compte de la casse ni des accents. Cette opérateur ne recherche que de façon textuelle, vous pouvez ajouter des '*' en début et fin de d'expression:

WikittyQuery q = new WikittyQueryMaker()
.like(User.ELEMENT_FIELD_USER_FIRSTNAME, "helene").end();
WikittyQuery q = new WikittyQueryMaker()
.like(User.ELEMENT_FIELD_USER_FIRSTNAME, "*lene").end();

WikittyQuery q = WikittyQueryParser.parse("User.fistname LIKE helene");
WikittyQuery q = WikittyQueryParser.parse("User.fistname LIKE *lene");

Non similitude : unlike

Vérifie qu'une chaîne de caractère n'est pas égale à une autre sans tenir compte de la casse ni des accents. Cette opérateur ne recherche que de façon textuelle, vous pouvez ajouter des '*' en début et fin de d'expression:

WikittyQuery q = new WikittyQueryMaker()
.unlike(User.ELEMENT_FIELD_USER_FIRSTNAME, "helene").end();
WikittyQuery q = new WikittyQueryMaker()
.unlike(User.ELEMENT_FIELD_USER_FIRSTNAME, "*lene").end();

WikittyQuery q = WikittyQueryParser.parse("User.fistname UNLIKE helene");
WikittyQuery q = WikittyQueryParser.parse("User.fistname UNLIKE *lene");

Supérieur strictement : gt

Vérifie qu'un champ est strictement supérieur à une valeur. Cette condition s'applique surtout sur les champs de type Date et Number:

WikittyQuery q = new WikittyQueryMaker()
.gt(User.ELEMENT_FIELD_USER_AGE, 18).end();

WikittyQuery q = WikittyQueryParser.parse("User.age > 18");

Supérieur ou égal : ge

Vérifie si un champ est supérieur ou égal à une valeur.:

WikittyQuery q = new WikittyQueryMaker()
.ge(User.ELEMENT_FIELD_USER_AGE, 18).end();

WikittyQuery q = WikittyQueryParser.parse("User.age >= 18");

Inférieur strictement : lt

Vérifie si un champ est strictement inférieur à une valeur.:

WikittyQuery q = new WikittyQueryMaker()
.lt(User.ELEMENT_FIELD_USER_AGE, 18).end();

WikittyQuery q = WikittyQueryParser.parse("User.age < 18");

Inférieur ou égal : le

Vérifie si un champ est inférieur ou égal à une valeur.:

WikittyQuery q = new WikittyQueryMaker()
.le(User.ELEMENT_FIELD_USER_AGE, 18).end();

WikittyQuery q = WikittyQueryParser.parse("User.age <= 18");

Entre : bw

Vérifie si un champ est compris entre deux valeurs.:

WikittyQuery q = new WikittyQueryMaker()
.bw(Product.ELEMENT_FIELD_PRODUCT_PRICE, 2, 2.50).end();

WikittyQuery q = WikittyQueryParser.parse("Product.price=[2 TO 2.5]");

Commence par : sw

Vérifie si un champ de type chaîne commence par une valeur.:

WikittyQuery q = new WikittyQueryMaker()
.sw(User.ELEMENT_FIELD_USER_LASTNAME, "pous").end();

WikittyQuery q = WikittyQueryParser.parse("User.lastname=pous*");

Ne commence pas par : notsw

Vérifie si un champ de type chaîne ne commence pas par une valeur.:

WikittyQuery q = new WikittyQueryMaker()
.notsw(User.ELEMENT_FIELD_USER_LASTNAME, "pous").end();

WikittyQuery q = WikittyQueryParser.parse("User.lastname!=pous*");

Termine par : ew

Vérifie si un champ de type chaîne termine par une valeur.:

WikittyQuery q = new WikittyQueryMaker()
.ew(User.ELEMENT_FIELD_USER_LASTNAME, "sin").end();

WikittyQuery q = WikittyQueryParser.parse("User.lastname=*sin");

Ne termine pas par : notew

Vérifie si un champs de type chaîne ne termine pas par une valeur.:

WikittyQuery q = new WikittyQueryMaker()
.notew(User.ELEMENT_FIELD_USER_LASTNAME, "pous").end();

WikittyQuery q = WikittyQueryParser.parse("User.lastname!=*pous");

Mot-clé : keyword

Vérifie si la valeur est présente dans n'importe quel champ de n'importe quelle extension en fulltext (pas de prise en compte de la casse ou des accents).:

WikittyQuery q = new WikittyQueryMaker()
.keyword("partout").end();

WikittyQuery q = WikittyQueryParser.parse("partout");

Nul : isNull

Vérifie si la valeur d'un champ est nulle:

WikittyQuery q = new WikittyQueryMaker()
.isNull(User.ELEMENT_FIELD_USER_LASTNAME).end();

WikittyQuery q = WikittyQueryParser.parse("User.lastname=NULL");

Non nul : isNotNull

Vérifie si la valeur d'un champ n'est pas nulle.

WikittyQuery q = new WikittyQueryMaker()
.isNotNull(User.ELEMENT_FIELD_USER_LASTNAME).end();

WikittyQuery q = WikittyQueryParser.parse("User.lastname!=NULL");

False : rFalse

retourne toujours faux:

WikittyQuery q = new WikittyQueryMaker()
.rFalse().end();

WikittyQuery q = WikittyQueryParser.parse("FALSE");

True : rTrue

retourne toujours vrai:

WikittyQuery q = new WikittyQueryMaker()
.rTrue().end();

WikittyQuery q = WikittyQueryParser.parse("TRUE");

Les noeuds à sous-requête

Les noeuds à sous requêtes permettent de faire des requêtes complexes.

Non : not

Résultat inverse de la sous-requête. Permet de faire la négation d'une condition. On ne peut ajouter qu'une condition dans un not, il faut donc ajouter en premier soit un or, soit un and pour mettre plusieurs conditions:

WikittyQuery q = new WikittyQueryMaker()
.not().rFalse().end(); // condition toujours vraie

WikittyQuery q = WikittyQueryParser.parse("NOT(FALSE)");

WikittyQuery q = new WikittyQueryMaker()
.not().or().rFalse().rFalse().rTrue().end(); // condition toujours fausse

WikittyQuery q = WikittyQueryParser.parse("NOT(FALSE OR FALSE OR TRUE)");

Ou : or

Ou entre les différentes sous-requêtes. On peut ajouter autant d'élément dans le or que l'on souhaite, en fait les éléments lui sont ajouté tant qu'il n'est pas fermé (close).

WikittyQuery q = new WikittyQueryMaker()
.or().rFalse().rTrue().rFalse().end(); // condition toujours vrai

WikittyQuery q = WikittyQueryParser.parse("FALSE OR TRUE OR FALSE");

Et : and

Et entre les différentes sous-requêtes. On peut ajouter autant d'élément dans le and que l'on souhaite, en fait les éléments lui sont ajouté tant qu'il n'est pas fermé (close).

WikittyQuery q = new WikittyQueryMaker()
.and().rFalse().rTrue().rTrue().end(); // condition toujours fausse

WikittyQuery q = WikittyQueryParser.parse("FALSE AND TRUE AND TRUE"); WikittyQuery q = WikittyQueryParser.parse("FALSE TRUE TRUE");

Selection : select

Ajout d'un select pour définir le champs à retourner au lieu de l'id. Le select doit toujours être le premier élément de la condition ou utilisé à la place d'une valeur.

Attention le select provoque la génération d'une deuxième requête, donc plus il y a de select dans une requête plus elle demandera de ressource au serveur et donc des temps de réponse plus long.

Dans l'exemple suivant au lieu de retourner l'id des employés en CDI, on retourne leur nom. Si deux personnes avait le même nom, ce nom serait retourné deux fois sauf si la clause DISTINCT a été utilisé.:

WikittyQuery q = new WikittyQueryMaker()
select("Employee.name").eq("Employee.contract", "CDI").end();

WikittyQuery q = WikittyQueryParser.parse(
"SELECT Employee.name WHERE Employee.contract=CDI");

Il est possible de coupler le select et toutes les conditions terminales, par exemple pour recherche toutes les personnes nés le même jour qu'un évênement qui a eu lieu en france:

WikittyQuery q = new WikittyQueryMaker()
.containsOne("Person.birthday")
.select("Event.date").like("Event.country", "france").end();

WikittyQuery q = WikittyQueryParser.parse(
"Person.birthday={SELECT Event.date WHERE (Event.country LIKE france)}");

Il est possible d'ajouter des fonctions d'aggrégats dans le Select. Dans ce cas le résultat retourné ne contient qu'un seul élément. L'aggrégat est fait sur les élements retournés (de first à first+Limit). Il est aussi possible d'ajouter la clause DISTINCT pour que les éléments retournés ou les aggrégats se fassent seulement sur les éléments distincts.

DISTINCT

Retourne une liste sans doublon:

WikittyQuery q = new WikittyQueryMaker()
.select().distinct("Person.age").where().eq("Person.firstname", "Jean").end();

WikittyQuery q = WikittyQueryParser.parse(
"SELECT DISTINCT(Person.age) WHERE Person.firstname=Jean");

Dans ces exemples si plusieurs personnes portant le prénom 'Jean' ont le même âge, cet âge n'est retourné qu'une seule fois. Par exemple si la liste dans le DISTINCT retourne: 12, 18, 18, 33. Avec le DISTINCT le résultat sera: 12, 18, 33

Il est possible de couplé DISTINCT est une fonction d'aggrégat:

WikittyQuery q = new WikittyQueryMaker()
.select().avg().distinct("Person.age").where().eq("Person.firstname", "Jean").end();

WikittyQuery q = WikittyQueryParser.parse(
"SELECT AVG(DISTINCT(Person.age)) WHERE Person.firstname=Jean");

Dans cette exemple la moyenne est fait sur: 12, 18, 33 soit 21

AVG

Fait la moyenne des valeurs, il faut donc que le champs sélectionnés soit un Numeric:

WikittyQuery q = new WikittyQueryMaker()
.select().avg("Person.age").where().eq("Person.firstname", "Jean").end();

WikittyQuery q = WikittyQueryParser.parse(
"SELECT AVG(Person.age) WHERE Person.firstname=Jean");
COUNT

Retourne le nombre d'élément retourné:

WikittyQuery q = new WikittyQueryMaker()
.select().count("Person.age").where().eq("Person.firstname", "Jean").end();

WikittyQuery q = WikittyQueryParser.parse(
"SELECT COUNT(Person.age) WHERE Person.firstname=Jean");
MAX

Retourne la plus grande valeur. MAX peut-etre utilisé sur tout type de champs mais il est plus pertinant sur les champs: Numeric, Date, String:

// on recherche le plus jeune (plus grande date) des personnes s'appelant Jean
WikittyQuery q = new WikittyQueryMaker()
.select().max("Person.birthday").where().eq("Person.firstname", "Jean").end();

WikittyQuery q = WikittyQueryParser.parse(
"SELECT MAX(Person.birthday) WHERE Person.firstname=Jean");
MIN

Retourne la plus petite valeur. MIN peut-etre utilisé sur tout type de champs mais il est plus pertinant sur les champs: Numeric, Date, String:

// on recherche le plus agé (plus petite date) des personnes s'appelant Jean
WikittyQuery q = new WikittyQueryMaker()
.select().min("Person.birthday").where().eq("Person.firstname", "Jean").end();

WikittyQuery q = WikittyQueryParser.parse(
"SELECT MIN(Person.birthday) WHERE Person.firstname=Jean");
SUM

Retourne la somme de tous les nombres. Il faut donc que le champs sélectionné soit un Numeric:

// fait la somme des facture depuis le début d'année
WikittyQuery q = new WikittyQueryMaker()
.select().sum("Invoice.amount").where().ge("Invoice.date", "01/01/2012").end();

WikittyQuery q = WikittyQueryParser.parse(
"SELECT SUM(Invoice.amount) WHERE Invoice.date>=date(01/01/2012)");

Recherche sur les arbres

Pour la recherche sur les arbres 3 pseudos champs sont utilisables

  • rootNode: champs contenant l'id de la racine du noeud

  • pathNode: champs contenant tous les id de noeuds pour atteindre un noeud (du root au noeud lui même inclus)

  • depthNode: entier indiquant la profondeur d'un noeud (root=1)

Quelques exemples

Pour avoir tous les attachments de tous les noeuds de tous les arbres:

WikittyQuery q = new WikittyQueryMaker()
.containsOne(Element.ID)
.select(WikittyTreeNode.ELEMENT_FIELD_WIKITTYTREENODE_ATTACHMENT).where().exteq(WikittyTreeNode.EXT_WIKITTY_TREE_NODE).end();

WikittyQuery q = WikittyQueryParser.parse(
"id={SELECT WikittyTreeNode.attachment where extension=WikittyTreeNode}");

Pour avoir tous les attachments de tous les noeuds d'un arbre ayant le nom 'MyTree':

WikittyQuery q = new WikittyQueryMaker()
.containsOne(Element.ID)
.select(WikittyTreeNode.ELEMENT_FIELD_WIKITTYTREENODE_ATTACHMENT)
.containsOne(Element.ROOT_NODE)
.select(Element.ID)
.eq(WikittyTreeNode.ELEMENT_FIELD_WIKITTYTREENODE_NAME, "MyTree").end();

WikittyQuery q = WikittyQueryParser.parse(
"id={SELECT WikittyTreeNode.attachment WHERE rootNode={SELECT id WHERE (WikittyTreeNode.name=MyTree)}");

Pour avoir tous les attachments d'un sous arbre commencant à un noeud ayant le nom "MyBranch" d'un arbre ayant le nom 'MyTree':

WikittyQuery q = new WikittyQueryMaker()
.containsOne(Element.ID)
.select(WikittyTreeNode.ELEMENT_FIELD_WIKITTYTREENODE_ATTACHMENT)
.and()
.containsOne(Element.ROOT_NODE)
.select(Element.ID)
.eq(WikittyTreeNode.ELEMENT_FIELD_WIKITTYTREENODE_NAME, "MyTree")
.close();
.containsOne(Element.PATH_NODE)
.select(Element.ID)
.eq(WikittyTreeNode.ELEMENT_FIELD_WIKITTYTREENODE_NAME, "MyBranch").end();

WikittyQuery q = WikittyQueryParser.parse("id={SELECT WikittyTreeNode.attachment WHERE
+ " (rootNode={SELECT id WHERE (WikittyTreeNode.name=MyTree)} AND"
+ " pathNode={SELECT id WHERE (WikittyTreeNode.name=MyBranch)})}");

Pour avoir tous les attachments d'un arbre ayant le nom 'MyTree' jusqu'à une profondeur de 3 (root, fils, sous fils):

WikittyQuery q = new WikittyQueryMaker()
.containsOne(Element.ID)
.select(WikittyTreeNode.ELEMENT_FIELD_WIKITTYTREENODE_ATTACHMENT)
.and()
.containsOne(Element.ROOT_NODE)
.eq(WikittyTreeNode.ELEMENT_FIELD_WIKITTYTREENODE_NAME, "MyTree")
.close();
.le(Element.PATH_NODE, 3).end();

WikittyQuery q = WikittyQueryParser.parse("id={(SELECT WikittyTreeNode.attachment WHERE
+ " rootNode={SELECT Element.ID WHERE (WikittyTreeNode.name=MyTree)} AND pathNode<=3)}");

Limiter et étendre les recherches

Il est possible de restraindre la plage de résultats retournés. Mais aussi de demander à ce que les recherches se fasse aussi sur les relations entres objet pour une profondeur donnée.

offset

Indique le premier résultat qui doit être retourné.

Si on souhaite seulement les résultats à partir du 10ème:

WikittyQuery q = new WikittyQueryMaker().rTrue().end();
q.setOffset(10);

WikittyQuery q = WikittyQueryParser.parse("TRUE #offset 10");

limit

Indique le nombre de résultats qui doit être retournés.

Si on souhaite seulement avoir 20 résultats:

WikittyQuery q = new WikittyQueryMaker().rTrue().end();
q.setLimit(20);

WikittyQuery q = WikittyQueryParser.parse("TRUE #limit 20");

depth

Indique la profondeur de recherche, c'est à dire le nombre de fois que l'on suite les relations.

Par exemple si on a des 'Person' qui appartiennent à une 'Company'. 'Person' ne contient que l'id d'une company. Il faut donc faire des containsOne avec un select si on veut faire des contraintes sur les personnes appartenants à une company.

Si on souhaite toutes les personnes s'appelant Jean de la Company 'Code Lutin':

WikittyQuery q = WikittyQueryParser.parse("Couteau 'Code lutin' #depth 1");

Il faut faire attention car on ne travail pas sur le nom des champs, les recherches se font dans ce cas la toujours en fulltext. Donc vous pouvez avoir beaucoup plus de résultat qu'attendu. Mettre une profondeur de plus de 1 peut avoir des conséquences non négligeable sur les performances de recherche.

Spécificité de WikittyQueryMaker

conversion de type

Il est possible de passer en argument des méthodes des objets qui seront directement converti en leur representation String. Les types supportés sont BusinessEntity, Wikitty, Date, Calendar, Number, Boolean. Pour un objet Wikitty ou un BusinessEntity on utilise l'id.

Fermeture d'un noeud: close

Lorsqu'on ouvre un element a sous noeud comme or, and, il faut pouvoir le fermer pour continuer la construction de la condition. Pour cela on utilise close(), qui ferme la dernière condition non terminale.:

WikittyQuery q = new WikittyQueryMaker()
.and().or()....close(/*fermeture du or*/).close(/*fermeture du and*/)
.not().and().....end(/*fermeture de tous les elements non ferme (and)*/);

wikitty

Normalement si l'on passe un wikitty en parametre de méthode de WikittyQueryMaker, la condition se fait sur l'id (voir conversion de type), mais on peut vouloir que le Wikitty soit pris comme exemple de condition (query by exemple), dans ce cas, on peut utiliser:

WikittyQuery q = new WikittyQueryMaker()
.wikitty(monWikitty).end();

Condition

Il est aussi possible d'ajouter toute une condition déjà construite pour l'intégrer à une nouvelle. Dans ce cas cette condition est prise comme une boîte noire, c'est à dire comme une condition terminale.:

WikittyQuery qold = ...

WikittyQuery q = new WikittyQueryMaker()
.and().condition(qold.getCondition()).eq(...).end();

Spécificité de WikittyQueryParser

Date

Pour simplifier l'écriture des dates, il est possible d'utiliser la fonction date, ce qui évite de devoir écrire les dates dans un format spécifique.:

WikittyQuery q = WikittyQueryParser.parse(
"SELECT MIN(Person.birthday) WHERE Person.firstname=Jean and Person.birthday < date(01/01/2000)");

Ici on recherche une personne s'appelant 'Jean' ayant l'âge le plus petit, mais dont l'âge est tout de même avant l'an 2000.

Il est possible de faire de l'arithmetique sur les dates:

  • NOW+1DAY

  • TODAY+3MONTHS

  • date(12/12/2014+3HOURS)

  • /HOUR, arrondi à l'heure (0min, 0s,0ms)

  • /DAY, arrondi début de la journée

  • =????1130, garde l'année mais fixe le jour au 30 novembre

  • :12??30, garde les minute, mais fixe l'heure (12) et les secondes (30)

  • +2YEARS, ajoute 2 ans a la date

  • -1DAY, retire un jour a la date

  • /DAY+6MONTHS+3DAYS, arroudi la date au debut du jour, et ajoute 6 mois et 3 jours

  • +6MONTHS+3DAYS/DAY, ajoute 6 mois et 3 jours et arrondi au debut du jour

Alias

Vous pouvez ajouter des alias pour simplifier l'écriture de certaines requêtes.

Par exemple si vous utilisez souvent une longue requête comme:

WikittyQuery q = WikittyQueryParser.parse(
"id={SELECT WikittyTreeNode.attachment"
+ " WHERE (rootNode={SELECT ID WHERE (WikittyTreeNode.name=MyTree)}"
+ " AND pathNode={SELECT ID WHERE (WikittyTreeNode.name=MyBranch)})}");

Vous pouvez faire:

WikittyQueryParser parser = new WikittyQueryParser();
parser.addAlias("MyAlias", "id={SELECT WikittyTreeNode.attachment"
+ " WHERE (rootNode={SELECT ID WHERE (WikittyTreeNode.name=MyTree)}"
+ " AND pathNode={SELECT ID WHERE (WikittyTreeNode.name=MyBranch)})}");

Si maintenant votre requête est:

WikittyQuery q = parser.parseQuery(
"MyExt.field=toto AND MyAlias");

Elle sera transformée avant d'être parsée en:

WikittyQuery q = parser.parseQuery(
"MyExt.field=toto AND id={SELECT WikittyTreeNode.attachment"
+ " WHERE (rootNode={SELECT ID WHERE (WikittyTreeNode.name=MyTree)}"
+ " AND pathNode={SELECT ID WHERE (WikittyTreeNode.name=MyBranch)})}");

Vous pouvez aussi paramètrer vos alias, par exemple si le nom de l'arbre et de la branche doivent varier vous pouvez faire:

WikittyQueryParser parser = new WikittyQueryParser();
parser.addAlias("MyAlias(.*, .*)", "id={SELECT WikittyTreeNode.attachment"
+ " WHERE (rootNode={SELECT ID WHERE (WikittyTreeNode.name=$1)}"
+ " AND pathNode={SELECT ID WHERE (WikittyTreeNode.name=$2)})}");

Vous pourrez donc ensuite écrire:

WikittyQuery q = parser.parseQuery(
"MyExt.field=toto AND MyAlias(OtherTree, OtherBranch)");

Elle sera transformée avant d'être parsée en:

WikittyQuery q = parser.parseQuery(
"MyExt.field=toto AND id={SELECT WikittyTreeNode.attachment"
+ " WHERE (rootNode={SELECT ID WHERE (WikittyTreeNode.name=OtherTree)}"
+ " AND pathNode={SELECT ID WHERE (WikittyTreeNode.name=OtherBranch)})}");

Recherche avancée

Si vous souhaitez mettre des espaces dans une expression texte avec le parser il faut utiliser les guillemets pour encadrer la chaine.:

WikittyQuery q = WikittyQueryParser.parse("simple OR "la jolie chaine que je recherche"");

Il est possible de faire une recherche sur un nom de champs qui peut⁻être utilisé par différentes extensions. Pour cela on remplace le nom d'extension par '*':

WikittyQuery q = new WikittyQueryMaker()
.eq(new ElementField(ElementField.ALL_EXTENSION, "name"), "poussin").end();

WikittyQuery q = WikittyQueryParser.parse("*.name==poussin");

Dans ce cas la recherche est une recherche fulltext qui peut-être utilisée quelque soit le type du champs. Mais si vous souhaitez restraindre la recherche aux champs d'un certain type vous pouvez ajouter le type à la fin.:

Date _1950 = new Date(...);
Date _1960 = new Date(...);
WikittyQuery q = new WikittyQueryMaker()
bw.(new ElementField("birthday", FieldType.TYPE.DATE), _1950, _1960).end();

WikittyQuery q = WikittyQueryParser.parse("*.birthday.DATE=["01/01/1950" TO "01/01/1961"]");

Il est aussi possible de faire une recherche fulltext, c'est à dire sur tous les champs de toutes les extentions:

Date _1950 = new Date(...);
Date _1960 = new Date(...);
WikittyQuery q = new WikittyQueryMaker()
eq.(Element.ALL_FIELD, "poussin).end();

WikittyQuery q = WikittyQueryParser.parse("*=poussin");

Les autres paramètres d'une requête

  • Nom : name - Nommage de la requête.

  • Premier index : offset - Permet de définir le premier index à retourner. Principalement utilisé pour la pagination.

  • Nombre : limit - Permet de définir le nombre de résultat à retourner. Principalement utilisé pour la pagination.

  • facetMinCount: les topics des facettes ayant moins d'occurence que cette valeur ne sont pas retournés

  • facetLimit: les facettes ramènent au plus ce nombre de topics

  • facetSort: détermine l'ordre de tri des topics. Il est possible de trier sur le nombre d'occurences du topic ou le nom du topic

  • facetExtension indique de créer une facette sur les extensions des wikitties

  • facetField indique de créer une facette sur un champs

  • facetQuery indique de créer une facette grace a une condition. Par exemple au lieu de creer une facette sur Product.price qui retournerait trop de topics il est préférable de créer plusieurs facetQuery pour regrouper des prix:

    query.addFacetQuery("0-5", new WikittyQueryMaker().bw("Product.price", 0, 5));
    query.addFacetQuery("5-10", new WikittyQueryMaker().bw("Product.price", 5, 10));
    query.addFacetQuery("10-+", new WikittyQueryMaker().gt("Product.price", 10));
  • Tri : sortAscending - Ajout d'un ou plusieurs champs pour le tri ascendant du résultat.

  • Tri : sortDescending - Ajout d'un ou plusieurs champs pour le tri descendant du résultat.

Les résultats

Lorsqu'on effectue une recherche, on obtient un WikittyQueryResult. En effet, les résultats étant paginés, on obtient tout ou partie des résultats. Un WikittyQueryResult contient le nombre total de résultats, les résultats de la page ainsi que le premier index, le nombre de résultats et les facettes si elles ont été utilisées pour la recherche.