use of edu.harvard.iq.dataverse.search.SolrQueryResponse in project dataverse by IQSS.
the class Index method searchDebug.
/**
* This method is for integration tests of search.
*/
@GET
@Path("test")
public Response searchDebug(@QueryParam("key") String apiToken, @QueryParam("q") String query, @QueryParam("fq") final List<String> filterQueries) {
User user = findUserByApiToken(apiToken);
if (user == null) {
return error(Response.Status.UNAUTHORIZED, "Invalid apikey '" + apiToken + "'");
}
Dataverse subtreeScope = dataverseService.findRootDataverse();
String sortField = SearchFields.ID;
String sortOrder = SortBy.ASCENDING;
int paginationStart = 0;
boolean dataRelatedToMe = false;
int numResultsPerPage = Integer.MAX_VALUE;
SolrQueryResponse solrQueryResponse;
try {
solrQueryResponse = searchService.search(createDataverseRequest(user), subtreeScope, query, filterQueries, sortField, sortOrder, paginationStart, dataRelatedToMe, numResultsPerPage);
} catch (SearchException ex) {
return error(Response.Status.INTERNAL_SERVER_ERROR, ex.getLocalizedMessage() + ": " + ex.getCause().getLocalizedMessage());
}
JsonArrayBuilder itemsArrayBuilder = Json.createArrayBuilder();
List<SolrSearchResult> solrSearchResults = solrQueryResponse.getSolrSearchResults();
for (SolrSearchResult solrSearchResult : solrSearchResults) {
itemsArrayBuilder.add(solrSearchResult.getType() + ":" + solrSearchResult.getNameSort());
}
return ok(itemsArrayBuilder);
}
use of edu.harvard.iq.dataverse.search.SolrQueryResponse in project dataverse by IQSS.
the class Search method search.
@GET
public Response search(@QueryParam("q") String query, @QueryParam("type") final List<String> types, @QueryParam("subtree") String subtreeRequested, @QueryParam("sort") String sortField, @QueryParam("order") String sortOrder, @QueryParam("per_page") final int numResultsPerPageRequested, @QueryParam("start") final int paginationStart, @QueryParam("show_relevance") boolean showRelevance, @QueryParam("show_facets") boolean showFacets, @QueryParam("fq") final List<String> filterQueries, @QueryParam("show_entity_ids") boolean showEntityIds, @QueryParam("show_api_urls") boolean showApiUrls, @QueryParam("show_my_data") boolean showMyData, @Context HttpServletResponse response) {
User user;
try {
user = getUser();
} catch (WrappedResponse ex) {
return ex.getResponse();
}
if (query != null) {
// sanity checking on user-supplied arguments
SortBy sortBy;
int numResultsPerPage;
Dataverse subtree;
try {
if (!types.isEmpty()) {
filterQueries.add(getFilterQueryFromTypes(types));
}
sortBy = SearchUtil.getSortBy(sortField, sortOrder);
numResultsPerPage = getNumberOfResultsPerPage(numResultsPerPageRequested);
subtree = getSubtree(subtreeRequested);
if (!subtree.equals(dataverseService.findRootDataverse())) {
String dataversePath = dataverseService.determineDataversePath(subtree);
String filterDownToSubtree = SearchFields.SUBTREE + ":\"" + dataversePath + "\"";
/**
* @todo Should filterDownToSubtree logic be centralized in
* SearchServiceBean?
*/
filterQueries.add(filterDownToSubtree);
}
} catch (Exception ex) {
return error(Response.Status.BAD_REQUEST, ex.getLocalizedMessage());
}
// users can't change these (yet anyway)
// getDataRelatedToMe();
boolean dataRelatedToMe = showMyData;
SolrQueryResponse solrQueryResponse;
try {
solrQueryResponse = searchService.search(createDataverseRequest(user), subtree, query, filterQueries, sortBy.getField(), sortBy.getOrder(), paginationStart, dataRelatedToMe, numResultsPerPage);
} catch (SearchException ex) {
Throwable cause = ex;
StringBuilder sb = new StringBuilder();
sb.append(cause + " ");
while (cause.getCause() != null) {
cause = cause.getCause();
sb.append(cause.getClass().getCanonicalName() + " ");
sb.append(cause + " ");
// if you search for a colon you see RemoteSolrException: org.apache.solr.search.SyntaxError: Cannot parse ':'
}
String message = "Exception running search for [" + query + "] with filterQueries " + filterQueries + " and paginationStart [" + paginationStart + "]: " + sb.toString();
logger.info(message);
return error(Response.Status.INTERNAL_SERVER_ERROR, message);
}
JsonArrayBuilder itemsArrayBuilder = Json.createArrayBuilder();
List<SolrSearchResult> solrSearchResults = solrQueryResponse.getSolrSearchResults();
for (SolrSearchResult solrSearchResult : solrSearchResults) {
itemsArrayBuilder.add(solrSearchResult.toJsonObject(showRelevance, showEntityIds, showApiUrls));
}
JsonObjectBuilder spelling_alternatives = Json.createObjectBuilder();
for (Map.Entry<String, List<String>> entry : solrQueryResponse.getSpellingSuggestionsByToken().entrySet()) {
spelling_alternatives.add(entry.getKey(), entry.getValue().toString());
}
JsonArrayBuilder facets = Json.createArrayBuilder();
JsonObjectBuilder facetCategoryBuilder = Json.createObjectBuilder();
for (FacetCategory facetCategory : solrQueryResponse.getFacetCategoryList()) {
JsonObjectBuilder facetCategoryBuilderFriendlyPlusData = Json.createObjectBuilder();
JsonArrayBuilder facetLabelBuilderData = Json.createArrayBuilder();
for (FacetLabel facetLabel : facetCategory.getFacetLabel()) {
JsonObjectBuilder countBuilder = Json.createObjectBuilder();
countBuilder.add(facetLabel.getName(), facetLabel.getCount());
facetLabelBuilderData.add(countBuilder);
}
facetCategoryBuilderFriendlyPlusData.add("friendly", facetCategory.getFriendlyName());
facetCategoryBuilderFriendlyPlusData.add("labels", facetLabelBuilderData);
facetCategoryBuilder.add(facetCategory.getName(), facetCategoryBuilderFriendlyPlusData);
}
facets.add(facetCategoryBuilder);
JsonObjectBuilder value = Json.createObjectBuilder().add("q", query).add("total_count", solrQueryResponse.getNumResultsFound()).add("start", solrQueryResponse.getResultsStart()).add("spelling_alternatives", spelling_alternatives).add("items", itemsArrayBuilder.build());
if (showFacets) {
value.add("facets", facets);
}
value.add("count_in_response", solrSearchResults.size());
// value.add("fq_provided", filterQueries.toString());
if (solrQueryResponse.getError() != null) {
/**
* @todo You get here if you pass only ":" as a query, for
* example. Should we return more or better information?
*/
return error(Response.Status.BAD_REQUEST, solrQueryResponse.getError());
}
response.setHeader("Access-Control-Allow-Origin", "*");
return allowCors(ok(value));
} else {
return allowCors(error(Response.Status.BAD_REQUEST, "q parameter is missing"));
}
}
use of edu.harvard.iq.dataverse.search.SolrQueryResponse in project dataverse by IQSS.
the class SavedSearchServiceBean method findHits.
private SolrQueryResponse findHits(SavedSearch savedSearch) throws SearchException {
String sortField = SearchFields.RELEVANCE;
String sortOrder = SortBy.DESCENDING;
SortBy sortBy = new SortBy(sortField, sortOrder);
int paginationStart = 0;
boolean dataRelatedToMe = false;
int numResultsPerPage = Integer.MAX_VALUE;
SolrQueryResponse solrQueryResponse = searchService.search(new DataverseRequest(savedSearch.getCreator(), getHttpServletRequest()), savedSearch.getDefinitionPoint(), savedSearch.getQuery(), savedSearch.getFilterQueriesAsStrings(), sortBy.getField(), sortBy.getOrder(), paginationStart, dataRelatedToMe, numResultsPerPage);
return solrQueryResponse;
}
use of edu.harvard.iq.dataverse.search.SolrQueryResponse in project dataverse by IQSS.
the class DataRetrieverAPI method getTotalCountsFromSolr.
private SolrQueryResponse getTotalCountsFromSolr(DataverseRequest dataverseRequest, MyDataFinder myDataFinder) {
if (myDataFinder == null) {
throw new NullPointerException("myDataFinder cannot be null");
}
if (dataverseRequest == null) {
throw new NullPointerException("dataverseRequest cannot be null");
}
// -------------------------------------------------------
// Create new filter params that only check by the User
// -------------------------------------------------------
MyDataFilterParams filterParams = new MyDataFilterParams(dataverseRequest, myDataFinder.getRolePermissionHelper());
if (filterParams.hasError()) {
logger.severe("getTotalCountsFromSolr. filterParams error: " + filterParams.getErrorMessage());
return null;
}
// -------------------------------------------------------
// Re-run all of the entity queries (sigh)
// -------------------------------------------------------
myDataFinder.initFields();
myDataFinder.runFindDataSteps(filterParams);
if (myDataFinder.hasError()) {
logger.severe("getTotalCountsFromSolr. myDataFinder error: " + myDataFinder.getErrorMessage());
return null;
}
// -------------------------------------------------------
// Generate filterQueries for total counts
// -------------------------------------------------------
List<String> filterQueries = myDataFinder.getSolrFilterQueriesForTotalCounts();
if (filterQueries == null) {
logger.severe("getTotalCountsFromSolr. filterQueries was null!");
return null;
}
// msgt("getTotalCountsFromSolr");
// msgt(StringUtils.join(filterQueries, " AND "));
// -------------------------------------------------------
// Run Solr
// -------------------------------------------------------
SolrQueryResponse solrQueryResponseForCounts;
try {
solrQueryResponseForCounts = searchService.search(dataverseRequest, // subtree, default it to Dataverse for now
null, // Get everything--always
"*", // filterQueries,
filterQueries, SearchFields.NAME_SORT, SortBy.ASCENDING, // paginationStart,
0, // dataRelatedToMe
true, // 10 // SearchFields.NUM_SOLR_DOCS_TO_RETRIEVE
SearchConstants.NUM_SOLR_DOCS_TO_RETRIEVE);
} catch (SearchException ex) {
logger.severe("Search for total counts failed with filter query");
logger.severe("filterQueries: " + StringUtils.join(filterQueries, "(separator)"));
return null;
}
return solrQueryResponseForCounts;
}
use of edu.harvard.iq.dataverse.search.SolrQueryResponse in project dataverse by IQSS.
the class SavedSearchServiceBean method makeLinksForSingleSavedSearch.
/**
* The "Saved Search" and highly related "Linked Dataverses and Linked
* Datasets" features can be thought of as periodic execution of the
* LinkDataverseCommand and LinkDatasetCommand. As of this writing that
* periodic execution can be triggered via a cron job but we'd like to put
* it on an EJB timer as part of
* https://github.com/IQSS/dataverse/issues/2543 .
*
* The commands are executed by the creator of the SavedSearch. What happens
* if the users loses the permission that the command requires? Should the
* commands continue to be executed periodically as some "system" user?
*
* @return Debug information in the form of a JSON object, which is much
* more structured that a simple String.
*/
public JsonObjectBuilder makeLinksForSingleSavedSearch(DataverseRequest dvReq, SavedSearch savedSearch, boolean debugFlag) throws SearchException, CommandException {
JsonObjectBuilder response = Json.createObjectBuilder();
JsonArrayBuilder savedSearchArrayBuilder = Json.createArrayBuilder();
JsonArrayBuilder infoPerHit = Json.createArrayBuilder();
SolrQueryResponse queryResponse = findHits(savedSearch);
for (SolrSearchResult solrSearchResult : queryResponse.getSolrSearchResults()) {
JsonObjectBuilder hitInfo = Json.createObjectBuilder();
hitInfo.add("name", solrSearchResult.getNameSort());
hitInfo.add("dvObjectId", solrSearchResult.getEntityId());
DvObject dvObjectThatDefinitionPointWillLinkTo = dvObjectService.findDvObject(solrSearchResult.getEntityId());
if (dvObjectThatDefinitionPointWillLinkTo == null) {
hitInfo.add(resultString, "Could not find DvObject with id " + solrSearchResult.getEntityId());
infoPerHit.add(hitInfo);
break;
}
if (dvObjectThatDefinitionPointWillLinkTo.isInstanceofDataverse()) {
Dataverse dataverseToLinkTo = (Dataverse) dvObjectThatDefinitionPointWillLinkTo;
if (wouldResultInLinkingToItself(savedSearch.getDefinitionPoint(), dataverseToLinkTo)) {
hitInfo.add(resultString, "Skipping because dataverse id " + dataverseToLinkTo.getId() + " would link to itself.");
} else if (alreadyLinkedToTheDataverse(savedSearch.getDefinitionPoint(), dataverseToLinkTo)) {
hitInfo.add(resultString, "Skipping because dataverse " + savedSearch.getDefinitionPoint().getId() + " already links to dataverse " + dataverseToLinkTo.getId() + ".");
} else if (dataverseToLinkToIsAlreadyPartOfTheSubtree(savedSearch.getDefinitionPoint(), dataverseToLinkTo)) {
hitInfo.add(resultString, "Skipping because " + dataverseToLinkTo + " is already part of the subtree for " + savedSearch.getDefinitionPoint());
} else {
DataverseLinkingDataverse link = commandEngine.submitInNewTransaction(new LinkDataverseCommand(dvReq, savedSearch.getDefinitionPoint(), dataverseToLinkTo));
hitInfo.add(resultString, "Persisted DataverseLinkingDataverse id " + link.getId() + " link of " + dataverseToLinkTo + " to " + savedSearch.getDefinitionPoint());
}
} else if (dvObjectThatDefinitionPointWillLinkTo.isInstanceofDataset()) {
Dataset datasetToLinkTo = (Dataset) dvObjectThatDefinitionPointWillLinkTo;
if (alreadyLinkedToTheDataset(savedSearch.getDefinitionPoint(), datasetToLinkTo)) {
hitInfo.add(resultString, "Skipping because dataverse " + savedSearch.getDefinitionPoint() + " already links to dataset " + datasetToLinkTo + ".");
} else if (datasetToLinkToIsAlreadyPartOfTheSubtree(savedSearch.getDefinitionPoint(), datasetToLinkTo)) {
// already there from normal search/browse
hitInfo.add(resultString, "Skipping because dataset " + datasetToLinkTo.getId() + " is already part of the subtree for " + savedSearch.getDefinitionPoint().getAlias());
} else if (datasetAncestorAlreadyLinked(savedSearch.getDefinitionPoint(), datasetToLinkTo)) {
hitInfo.add(resultString, "FIXME: implement this?");
} else {
DatasetLinkingDataverse link = commandEngine.submitInNewTransaction(new LinkDatasetCommand(dvReq, savedSearch.getDefinitionPoint(), datasetToLinkTo));
hitInfo.add(resultString, "Persisted DatasetLinkingDataverse id " + link.getId() + " link of " + link.getDataset() + " to " + link.getLinkingDataverse());
}
} else if (dvObjectThatDefinitionPointWillLinkTo.isInstanceofDataFile()) {
hitInfo.add(resultString, "Skipping because the search matched a file. The matched file id was " + dvObjectThatDefinitionPointWillLinkTo.getId() + ".");
} else {
hitInfo.add(resultString, "Unexpected DvObject type.");
}
infoPerHit.add(hitInfo);
}
JsonObjectBuilder info = getInfo(savedSearch, infoPerHit);
if (debugFlag) {
info.add("debug", getDebugInfo(savedSearch));
}
savedSearchArrayBuilder.add(info);
response.add("hits for saved search id " + savedSearch.getId(), savedSearchArrayBuilder);
return response;
}
Aggregations