Query Builder API query-builder-api
Funktionen i Resursdelningens frågebyggare exponeras via ett Java API och ett REST API. I det här avsnittet beskrivs dessa API:er.
Frågeverktyget på serversidan ( QueryBuilder
) kan acceptera en frågebeskrivning, skapa och köra en XPath-fråga, eventuellt filtrera resultatuppsättningen och även extrahera ansikten, om så önskas.
Frågebeskrivningen är helt enkelt en uppsättning predikat (Predicate
). Exempel är ett fulltextpredikat, som motsvarar jcr:contains()
i XPath.
För varje predikattyp finns det en utvärderingskomponent (PredicateEvaluator
) som kan hantera det specifika predikatet för XPath, filtrering och facet-extrahering. Det är mycket enkelt att skapa anpassade utvärderare, som kopplas in via OSGi-komponentkörningen.
REST API ger åtkomst till exakt samma funktioner via HTTP med svar som skickas i JSON.
Gem-session gem-session
AEM Gems är en serie tekniska djupdykningar i Adobe Experience Manager som levereras av experter från Adobe. Den här sessionen som är avsedd för frågebyggaren är mycket användbar för en översikt över och användning av verktyget.
Exempelfrågor sample-queries
Dessa exempel anges i Java-egenskapsformatsnotation. Om du vill använda dem med Java API:n använder du en Java HashMap
som i följande API-exempel.
För QueryBuilder
JSON Servlet innehåller varje exempel en länk till din lokala CQ-installation (på standardplatsen, http://localhost:4502
). Observera att du måste logga in på CQ-instansen innan du använder länkarna.
p.limit=-1
Returnera alla resultat returning-all-results
Följande fråga kommer att returnera tio resultat (eller för att vara exakt högst tio), men informera dig om Antal träffar: som faktiskt finns tillgängliga:
http://localhost:4502/bin/querybuilder.json?path=/content&1_property=sling:resourceType&1_property.value=foundation/components/text&1_property.operation=like&orderby=path
path=/content
1_property=sling:resourceType
1_property.value=foundation/components/text
1_property.operation=like
orderby=path
Samma fråga (med parametern p.limit=-1
) will returnera alla resultat (detta kan vara ett högt tal beroende på din instans):
http://localhost:4502/bin/querybuilder.json?path=/content&1_property=sling:resourceType&1_property.value=foundation/components/text&1_property.operation=like&p.limit=-1&orderby=path
path=/content
1_property=sling:resourceType
1_property.value=foundation/components/text
1_property.operation=like
p.limit=-1
orderby=path
Använda p.gissningssumma för att returnera resultaten using-p-guesstotal-to-return-the-results
Syftet med p.guessTotal
parametern är att returnera rätt antal resultat som kan visas genom att kombinera de lägsta p.offset- och p.limit-värdena. Fördelen med den här parametern är bättre prestanda med stora resultatuppsättningar. På så sätt undviker du att beräkna hela summan (t.ex. genom att anropa result.getSize()) och läsa hela resultatuppsättningen, optimerad hela vägen ned till OAK-motorn och indexvärdet. Detta kan vara en stor skillnad när det finns 100 000 resultat, både när det gäller körningstid och minnesanvändning.
Nackdelen med parametern är att användarna inte ser exakt summa. Men du kan ange ett minimivärde som p.gissningstotal=1000 så att det alltid läses upp till 1000, så du får exakta summor för mindre resultatuppsättningar, men om det är mer än så kan du bara visa"och mer".
Lägg till p.guessTotal=true
till frågan nedan för att se hur den fungerar:
http://localhost:4502/bin/querybuilder.json?path=/content&1_property=sling:resourceType&1_property.value=foundation/components/text&1_property.operation=like&p.guessTotal=true&orderby=path
path=/content
1_property=sling:resourceType
1_property.value=foundation/components/text
1_property.operation=like
p.guessTotal=true
orderby=path
Frågan returnerar p.limit
standard för 10
resultat med 0
förskjutning:
"success": true,
"results": 10,
"total": 10,
"more": true,
"offset": 0,
Från och med AEM 6.0 SP2 kan du även använda ett numeriskt värde för att räkna upp till ett anpassat antal maximala resultat. Använd samma fråga som ovan, men ändra värdet för p.guessTotal
till 50
:
http://localhost:4502/bin/querybuilder.json?path=/content&1_property=sling:resourceType&1_property.value=foundation/components/text&1_property.operation=like&p.guessTotal=50&orderby=path
Den returnerar ett tal som är lika med standardgränsen på 10 resultat med förskjutningen 0, men som bara visar maximalt 50 resultat:
"success": true,
"results": 10,
"total": 50,
"more": true,
"offset": 0,
Implementera sidnumrering implementing-pagination
Som standard ger Query Builder även antalet träffar. Beroende på den resulterande storleken kan det ta lång tid att fastställa det korrekta antalet, bland annat genom att kontrollera alla resultat för åtkomstkontroll. För det mesta används summan för att implementera sidnumrering för slutanvändargränssnittet. Eftersom det kan ta lång tid att fastställa det exakta antalet rekommenderar vi att du använder funktionen gissaTotal för att implementera sidnumreringen.
Gränssnittet kan till exempel anpassa följande metod:
-
Hämta och visa korrekt antal av totalt antal träffar (SearchResult.getTotalMatches() eller summan i querybuilder.json-svaret) är mindre än eller lika med 100,
-
Ange
guessTotal
till 100 när du anropar Query Builder. -
Svaret kan ha följande resultat:
total=43
,more=false
- Anger att det totala antalet träffar är 43. Gränssnittet kan visa upp till tio resultat som en del av den första sidan och ge sidnumrering för de kommande tre sidorna. Du kan också använda den här implementeringen för att visa en beskrivande text som "43 resultat hittades".total=100
,more=true
- Anger att det totala antalet träffar är större än 100 och att det exakta antalet inte är känt. Gränssnittet kan visas upp till tio som en del av den första sidan och sidnumreringen kan göras för de kommande tio sidorna. Du kan också använda den här för att visa text som "fler än 100 resultat hittades". När användaren går till nästa sida kommer ett anrop till Query Builder att öka gränsen förguessTotal
ochoffset
ochlimit
parametrar.
guessTotal
bör också användas i de fall där användargränssnittet behöver använda oändlig rullning för att undvika att frågeverktyget avgör det exakta träffantalet.
Hitta jar-filer och beställ dem, nyaste först find-jar-files-and-order-them-newest-first
http://localhost:4502/bin/querybuilder.json?type=nt:file&nodename=*.jar&orderby=@jcr:content/jcr:lastModified&orderby.sort=desc
type=nt:file
nodename=*.jar
orderby=@jcr:content/jcr:lastModified
orderby.sort=desc
Söka efter alla sidor och sortera dem efter senaste ändring find-all-pages-and-order-them-by-last-modified
http://localhost:4502/bin/querybuilder.json?type=cq:Page&orderby=@jcr:content/cq:lastModified
type=cq:Page
orderby=@jcr:content/cq:lastModified
Söka efter alla sidor och sortera dem efter senast ändrade, men fallande find-all-pages-and-order-them-by-last-modified-but-descending
http://localhost:4502/bin/querybuilder.json?type=cq:Page&orderby=@jcr:content/cq:lastModified&orderby.sort=desc]
type=cq:Page
orderby=@jcr:content/cq:lastModified
orderby.sort=desc
Fulltextsökning, sorterad efter poäng fulltext-search-ordered-by-score
http://localhost:4502/bin/querybuilder.json?fulltext=Management&orderby=@jcr:score&orderby.sort=desc
fulltext=Management
orderby=@jcr:score
orderby.sort=desc
Sök efter sidor som taggats med en viss tagg search-for-pages-tagged-with-a-certain-tag
http://localhost:4502/bin/querybuilder.json?type=cq:Page&tagid=marketing:interest/product&tagid.property=jcr:content/cq:tags
type=cq:Page
tagid=marketing:interest/product
tagid.property=jcr:content/cq:tags
Använd tagid
som i exemplet om du känner till det explicita tagg-ID:t.
Använd tag
förutse taggens titelsökväg (utan blanksteg).
I föregående exempel söker du efter sidor ( cq:Page
noder) måste du använda den relativa sökvägen från den noden för tagid.property
predikat, vilket jcr:content/cq:tags
. Som standard är tagid.property
skulle helt enkelt cq:tags
.
Sök under flera sökvägar (med grupper) search-under-multiple-paths-using-groups
http://localhost:4502/bin/querybuilder.json?fulltext=Management&group.1_path=/content/geometrixx/en/company/management&group.2_path=/content/geometrixx/en/company/bod&group.p.or=true
fulltext=Management
group.p.or=true
group.1_path=/content/geometrixx/en/company/management
group.2_path=/content/geometrixx/en/company/bod
Den här frågan använder en grupp (med namnet " group
"), som används för att avgränsa deluttryck i en fråga, på samma sätt som parenteser gör i fler standardtecken. Den föregående frågan kan till exempel uttryckas i ett mer välbekant format som:
"Management" and ("/content/geometrixx/en/company/management" or "/content/geometrixx/en/company/bod")
I gruppen i exemplet finns path
predikatet används flera gånger. Om du vill differentiera och ordna de två instanserna av predikatet (ordningen krävs för vissa predikat) måste du prefix prefixet med N _ where
N är ordningsindex. I föregående exempel är resultatpredikaten 1_path
och 2_path
.
The p
in p.or
är en särskild avgränsare som anger att följande (i det här fallet en or
) är en parameter i gruppen, i motsats till ett underpredikt för gruppen, såsom 1_path
.
Om nej p.or
ges så att alla predikat är OCHed tillsammans, vilket innebär att varje resultat måste uppfylla alla prediktiv.
Sök efter egenskaper search-for-properties
Här söker du efter alla sidor i en viss mall med hjälp av cq:template
egenskap:
http://localhost:4502/bin/querybuilder.json?property=cq%3atemplate&property.value=%2fapps%2fgeometrixx%2ftemplates%2fhomepage&type=cq%3aPageContent
type=cq:PageContent
property=cq:template
property.value=/apps/geometrixx/templates/homepage
Detta har nackdelen med att jcr:content
noder på sidorna, inte själva sidorna, returneras. Du kan lösa detta genom att söka efter relativ sökväg:
http://localhost:4502/bin/querybuilder.json?property=jcr%3acontent%2fcq%3atemplate&property.value=%2fapps%2fgeometrixx%2ftemplates%2fhomepage&type=cq%3aPage
type=cq:Page
property=jcr:content/cq:template
property.value=/apps/geometrixx/templates/homepage
Sök efter flera egenskaper search-for-multiple-properties
När du använder egenskapspredikatet flera gånger måste du lägga till nummerprefixen igen:
http://localhost:4502/bin/querybuilder.json?1_property=jcr%3acontent%2fcq%3atemplate&1_property.value=%2fapps%2fgeometrixx%2ftemplates%2fhomepage&2_property=jcr%3acontent%2fjcr%3atitle&2_property.value=English&type=cq%3aPage
type=cq:Page
1_property=jcr:content/cq:template
1_property.value=/apps/geometrixx/templates/homepage
2_property=jcr:content/jcr:title
2_property.value=English
Sök efter flera egenskapsvärden search-for-multiple-property-values
Så här undviker du stora grupper när du vill söka efter flera värden för en egenskap ( "A" or "B" or "C"
) kan du ange flera värden för property
predikat:
http://localhost:4502/bin/querybuilder.json?property=jcr%3atitle&property.1_value=Products&property.2_value=Square&property.3_value=Events
property=jcr:title
property.1_value=Products
property.2_value=Square
property.3_value=Events
För flervärdesegenskaper kan du även kräva att flera värden matchar ( "A" and "B" and "C"
):
http://localhost:4502/bin/querybuilder.json?property=jcr%3atitle&property.and=true&property.1_value=test&property.2_value=foo&property.3_value=bar
property=jcr:title
property.and=true
property.1_value=test
property.2_value=foo
property.3_value=bar
Förfina vad som returneras refining-what-is-returned
Som standard returnerar JSON-servern för QueryBuilder en standarduppsättning med egenskaper för varje nod i sökresultatet (t.ex. sökväg, namn, titel). För att få kontroll över vilka egenskaper som returneras kan du göra något av följande:
Ange
p.hits=full
I så fall inkluderas alla egenskaper för varje nod:
http://localhost:4502/bin/querybuilder.json?p.hits=full&property=jcr%3atitle&property.value=Triangle
property=jcr:title
property.value=Triangle
p.hits=full
Använd
p.hits=selective
och ange de egenskaper som du vill hämta in
p.properties
avgränsat med blanksteg:
http://localhost:4502/bin/querybuilder.json?p.hits=selective&property=jcr%3atitle&property.value=Triangle
http://localhost:4502/bin/querybuilder.json?
p.hits=selective&p.properties=sling%3aresourceType%20jcr%3aprimaryType&property=jcr%3atitle&property.value=Triangle
property=jcr:title
property.value=Triangle
p.hits=selective
p.properties=sling:resourceType jcr:primaryType
En annan sak du kan göra är att ta med underordnade noder i QueryBuilder-svaret. För att kunna göra detta måste du ange
p.nodedepth=n
där n
är antalet nivåer som du vill att frågan ska returnera. Observera att för att en underordnad nod ska kunna returneras måste den anges av egenskapsväljaren
p.hits=full
Exempel:
http://localhost:4502/bin/querybuilder.json?p.hits=full&p.nodedepth=5&property=jcr%3atitle&property.value=Triangle
property=jcr:title
property.value=Triangle
p.hits=full
p.nodedepth=5
Fler prognoser morepredicates
Mer information om fler predikt finns i Referenssida för Query Builder-prediktion.
Du kan även kontrollera Javadoc för PredicateEvaluator
klasser. Javadoc för dessa klasser innehåller en lista med egenskaper som du kan använda.
Klassnamnets prefix (till exempel " similar
" in SimilarityPredicateEvaluator
) är huvudegenskap av klassen. Den här egenskapen är också namnet på predikatet som ska användas i frågan (i gemener).
För sådana huvudegenskaper kan du förkorta frågan och använda " similar=/content/en
" istället för den fullständigt kvalificerade varianten " similar.similar=/content/en
". Det fullständiga, kvalificerade formuläret måste användas för alla icke-huvudsakliga egenskaper i en klass.
Exempel på API-användning för frågebyggaren example-query-builder-api-usage
String fulltextSearchTerm = "Geometrixx";
// create query description as hash map (simplest way, same as form post)
Map<String, String> map = new HashMap<String, String>();
// create query description as hash map (simplest way, same as form post)
map.put("path", "/content");
map.put("type", "cq:Page");
map.put("group.p.or", "true"); // combine this group with OR
map.put("group.1_fulltext", fulltextSearchTerm);
map.put("group.1_fulltext.relPath", "jcr:content");
map.put("group.2_fulltext", fulltextSearchTerm);
map.put("group.2_fulltext.relPath", "jcr:content/@cq:tags");
// can be done in map or with Query methods
map.put("p.offset", "0"); // same as query.setStart(0) below
map.put("p.limit", "20"); // same as query.setHitsPerPage(20) below
Query query = builder.createQuery(PredicateGroup.create(map), session);
query.setStart(0);
query.setHitsPerPage(20);
SearchResult result = query.getResult();
// paging metadata
int hitsPerPage = result.getHits().size(); // 20 (set above) or lower
long totalMatches = result.getTotalMatches();
long offset = result.getStartIndex();
long numberOfPages = totalMatches / 20;
//Place the results in XML to return to client
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
//Start building the XML to pass back to the AEM client
Element root = doc.createElement( "results" );
doc.appendChild( root );
// iterating over the results
for (Hit hit : result.getHits()) {
String path = hit.getPath();
//Create a result element
Element resultel = doc.createElement( "result" );
root.appendChild( resultel );
Element pathel = doc.createElement( "path" );
pathel.appendChild( doc.createTextNode(path ) );
resultel.appendChild( pathel );
}
Samma fråga som körs över HTTP med JSON-servern (Query Builder):
http://localhost:4502/bin/querybuilder.json?path=/content&type=cq:Page&group.p.or=true&group.1_fulltext=Geometrixx&group.1_fulltext.relPath=jcr:content&group.2_fulltext=Geometrixx&group.2_fulltext.relPath=jcr:content/@cq:tags&p.offset=0&p.limit=20
Lagra och läsa in frågor storing-and-loading-queries
Frågor kan lagras i databasen så att du kan använda dem senare. The QueryBuilder
innehåller " storeQuery
metod med följande signatur:
void storeQuery(Query query, String path, boolean createFile, Session session) throws RepositoryException, IOException;
När du använder QueryBuilder#storeQuery
metod, den givna Query
lagras i databasen som en fil eller som en egenskap enligt createFile
argumentvärde. I följande exempel visas hur du sparar en Query
till banan /mypath/getfiles
som en fil:
builder.storeQuery(query, "/mypath/getfiles", true, session);
Tidigare lagrade frågor kan läsas in från databasen med QueryBuilder#loadQuery
metod:
Query loadQuery(String path, Session session) throws RepositoryException, IOException
Till exempel en Query
lagras i sökvägen /mypath/getfiles
kan läsas in med följande kodfragment:
Query loadedQuery = builder.loadQuery("/mypath/getfiles", session);
Testning och felsökning testing-and-debugging
Om du vill spela upp runt och felsöka frågor Builder-frågor kan du använda felsökningskonsolen för QueryBuilder på
http://localhost:4502/libs/cq/search/content/querydebug.html
eller också kan querybuilder json servlet på
http://localhost:4502/bin/querybuilder.json?path=/tmp
( path=/tmp
är bara ett exempel).
Allmän felsökning av Recommendations general-debugging-recommendations
Få förklarlig XPath via loggning obtain-explain-able-xpath-via-logging
Förklara alla frågar under utvecklingscykeln mot målindexuppsättningen.
-
Aktivera DEBUG-loggar för QueryBuilder för att få underliggande, förklarlig XPath-fråga
- Navigera till https://<serveraddress>:<serverport>/system/console/slinglog. Skapa en ny loggare för
com.day.cq.search.impl.builder.QueryImpl
på FELSÖKNING.
- Navigera till https://<serveraddress>:<serverport>/system/console/slinglog. Skapa en ny loggare för
-
När DEBUG har aktiverats för ovanstående klass visas den XPath som genererats av Query Builder i loggarna.
-
Kopiera XPath-frågan från loggposten för den associerade QueryBuilder-frågan, till exempel:
com.day.cq.search.impl.builder.QueryImpl XPath query: /jcr:root/content//element(*, cq:Page)[(jcr:contains(jcr:content, "Geometrixx") or jcr:contains(jcr:content/@cq:tags, "Geometrixx"))]
-
Klistra in XPath-frågan i Förklara fråga som XPath för att undertrycka frågeplanen
Hämta förklaringsbar XPath via felsökningsfunktionen i Query Builder obtain-explain-able-xpath-via-the-query-builder-debugger
- Använd AEM QueryBuilder-felsökningsprogrammet för att generera en förklarande XPath-fråga:
Förklara alla frågar under utvecklingscykeln mot målindexuppsättningen.
Få förklarlig XPath via loggning
-
Aktivera DEBUG-loggar för QueryBuilder för att få underliggande, förklarlig XPath-fråga
- Navigera till https://<serveraddress>:<serverport>/system/console/slinglog. Skapa en ny loggare för
com.day.cq.search.impl.builder.QueryImpl
på FELSÖKNING.
- Navigera till https://<serveraddress>:<serverport>/system/console/slinglog. Skapa en ny loggare för
-
När DEBUG har aktiverats för ovanstående klass visas den XPath som genererats av Query Builder i loggarna.
-
Kopiera XPath-frågan från loggposten för den associerade QueryBuilder-frågan, till exempel:
com.day.cq.search.impl.builder.QueryImpl XPath query: /jcr:root/content//element(*, cq:Page)[(jcr:contains(jcr:content, "Geometrixx") or jcr:contains(jcr:content/@cq:tags, "Geometrixx"))]
-
Klistra in XPath-frågan i Förklara fråga som XPath för att undertrycka frågeplanen
Hämta förklaringsbar XPath via felsökningsfunktionen i Query Builder
- Använd AEM QueryBuilder-felsökningsprogrammet för att generera en förklarande XPath-fråga:
- Ange frågan för Frågebyggaren i felsökningsprogrammet för Frågebyggaren
- Utför sökningen
- Hämta genererad XPath
- Klistra in XPath-frågan i XPath som XPath för att undertrycka frågeplanen
En demonstrationsvideo om hur du felsöker frågor med QueryBuilder finns nedan.
Felsöka frågor med loggning debugging-queries-with-logging
Loggutdata (INFO-nivå) för frågebyggarimplementeringen när frågan som beskrivs i Testa och felsöka körs:
com.day.cq.search.impl.builder.QueryImpl executing query (predicate tree):
null=group: limit=20, offset=0[
{group=group: or=true[
{1_fulltext=fulltext: fulltext=Geometrixx, relPath=jcr:content}
{2_fulltext=fulltext: fulltext=Geometrixx, relPath=jcr:content/@cq:tags}
]}
{path=path: path=/content}
{type=type: type=cq:Page}
]
com.day.cq.search.impl.builder.QueryImpl XPath query: /jcr:root/content//element(*, cq:Page)[(jcr:contains(jcr:content, "Geometrixx") or jcr:contains(jcr:content/@cq:tags, "Geometrixx"))]
com.day.cq.search.impl.builder.QueryImpl no filtering predicates
com.day.cq.search.impl.builder.QueryImpl query execution took 69 ms
Om du har en fråga med prediktiva utvärderare som filtrerar eller som använder en anpassad ordning efter jämförelseoperatorn, kommer detta även att noteras i frågan:
com.day.cq.search.impl.builder.QueryImpl executing query (predicate tree):
null=group: [
{nodename=nodename: nodename=*.jar}
{orderby=orderby: orderby=@jcr:content/jcr:lastModified}
{type=type: type=nt:file}
]
com.day.cq.search.impl.builder.QueryImpl custom order by comparator: jcr:content/jcr:lastModified
com.day.cq.search.impl.builder.QueryImpl XPath query: //element(*, nt:file)
com.day.cq.search.impl.builder.QueryImpl filtering predicates: {nodename=nodename: nodename=*.jar}
com.day.cq.search.impl.builder.QueryImpl query execution took 272 ms