X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fsolr.c;h=5863fe1aceb0646dc5e988688dd6e87ce53ea427;hp=701e9f3d0b3874f7eed2686aa74ddfff6edfb55f;hb=fe42f72dc30321041420cf2d1a83867b1c450f38;hpb=847dc126960b1bcc6ce8cef8a73e3606588770af diff --git a/src/solr.c b/src/solr.c index 701e9f3..5863fe1 100644 --- a/src/solr.c +++ b/src/solr.c @@ -1,10 +1,10 @@ /* This file is part of the YAZ toolkit. - * Copyright (C) 1995-2011 Index Data + * Copyright (C) 1995-2012 Index Data * See the file LICENSE for details. */ /** * \file solr.c - * \brief Implements SOAP Webservice decoding/encoding + * \brief Implements Solr decoding/encoding */ #if HAVE_CONFIG_H #include @@ -27,6 +27,15 @@ #include #include +static void extract_text_node(xmlNodePtr node, WRBUF wrbuf) { + xmlNodePtr child; + for (child = node->children; child ; child = child->next) + { + if (child->type == XML_TEXT_NODE) + wrbuf_puts(wrbuf, (const char *) child->content); + } +} + static int match_xml_node_attribute( xmlNodePtr ptr, const char *node_name, const char *attribute_name, const char *value) @@ -59,7 +68,7 @@ static void yaz_solr_decode_result_docs(ODR o, xmlNodePtr ptr, for (node = ptr->children; node; node = node->next) if (node->type == XML_ELEMENT_NODE) sr->num_records++; - + if (sr->num_records) sr->records = odr_malloc(o, sizeof(*sr->records) * sr->num_records); @@ -81,8 +90,6 @@ static void yaz_solr_decode_result_docs(ODR o, xmlNodePtr ptr, record->recordData_buf = odr_malloc(o, buf->use + 1); memcpy(record->recordData_buf, buf->content, buf->use); record->recordData_buf[buf->use] = '\0'; - // TODO Solve the real problem in zoom-sru, that doesnt work with 0-based indexes. - // Work-around: Making the recordPosition 1-based. record->recordPosition = odr_intdup(o, start + offset + 1); xmlBufferFree(buf); @@ -105,7 +112,7 @@ static int yaz_solr_decode_result(ODR o, xmlNodePtr ptr, { sr->numberOfRecords = odr_intdup(o, odr_atoi( (const char *) attr->children->content)); - } + } else if (!strcmp((const char *) attr->name, "start")) { start = odr_atoi((const char *) attr->children->content); @@ -194,6 +201,64 @@ static int yaz_solr_decode_facet_counts(ODR o, xmlNodePtr root, return 0; } +static void yaz_solr_decode_suggestion_values(xmlNodePtr listPptr, WRBUF wrbuf) +{ + xmlNodePtr node; + for (node = listPptr; node; node= node->next) { + if (!strcmp((char*) node->name, "lst")) { + xmlNodePtr child; + for (child = node->children; child; child= child->next) { + if (match_xml_node_attribute(child, "str", "name", "word")) { + wrbuf_puts(wrbuf, ""); + extract_text_node(child, wrbuf); + wrbuf_puts(wrbuf, "\n"); + } + } + } + } +} + +static void yaz_solr_decode_suggestion_lst(xmlNodePtr lstPtr, WRBUF wrbuf) +{ + xmlNodePtr node; + for (node = lstPtr; node; node= node->next) { + if (match_xml_node_attribute(node, "arr", "name", "suggestion")) { + yaz_solr_decode_suggestion_values(node->children, wrbuf); + } + } +} + +static void yaz_solr_decode_misspelled(xmlNodePtr lstPtr, WRBUF wrbuf) +{ + xmlNodePtr node; + for (node = lstPtr; node; node= node->next) + { + if (!strcmp((const char*) node->name, "lst")) { + const char *misspelled = yaz_element_attribute_value_get(node, "lst", "name"); + if (misspelled) { + wrbuf_printf(wrbuf, "\n", misspelled); + yaz_solr_decode_suggestion_lst(node->children, wrbuf); + wrbuf_puts(wrbuf, "\n"); + } + } + } +} + +static int yaz_solr_decode_spellcheck(ODR o, xmlNodePtr spellcheckPtr, Z_SRW_searchRetrieveResponse *sr) +{ + xmlNodePtr ptr; + WRBUF wrbuf = wrbuf_alloc(); + wrbuf_puts(wrbuf, ""); + for (ptr = spellcheckPtr->children; ptr; ptr = ptr->next) + { + if (match_xml_node_attribute(ptr, "lst", "name", "suggestions")) + { + yaz_solr_decode_misspelled(ptr->children, wrbuf); + } + } + sr->suggestions = odr_strdup(o, wrbuf_cstr(wrbuf)); + return 0; +} #endif int yaz_solr_decode_response(ODR o, Z_HTTP_Response *hres, Z_SRW_PDU **pdup) @@ -235,9 +300,12 @@ int yaz_solr_decode_response(ODR o, Z_HTTP_Response *hres, Z_SRW_PDU **pdup) /* TODO The check on hits is a work-around to avoid garbled facets on zero results from the SOLR server. * The work-around works because the results is before the facets in the xml. */ if (rc_result == 0 && *sr->numberOfRecords > 0 && - match_xml_node_attribute(ptr, "lst", "name", - "facet_counts")) + match_xml_node_attribute(ptr, "lst", "name", "facet_counts")) rc_facets = yaz_solr_decode_facet_counts(o, ptr, sr); + if (rc_result == 0 && *sr->numberOfRecords == 0 && + match_xml_node_attribute(ptr, "lst", "name", "spellcheck")) + rc_facets = yaz_solr_decode_spellcheck(o, ptr, sr); + } ret = rc_result + rc_facets; } @@ -300,7 +368,7 @@ static int yaz_solr_encode_facet_list( facet_list->elements[index]); if (r) return -1; - + } return 0; } @@ -314,8 +382,8 @@ int yaz_solr_encode_request(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, char *uri_args; char *path; int i = 0; - - z_HTTP_header_add_basic_auth(encode, &hreq->headers, + + z_HTTP_header_add_basic_auth(encode, &hreq->headers, srw_pdu->username, srw_pdu->password); if (srw_pdu->which == Z_SRW_searchRetrieve_request) { @@ -345,6 +413,15 @@ int yaz_solr_encode_request(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, yaz_add_name_value_str(encode, name, value, &i, "fl", request->recordSchema); + switch(srw_pdu->u.request->sort_type) + { + case Z_SRW_sort_type_none: + break; + case Z_SRW_sort_type_sort: + yaz_add_name_value_str(encode, name, value, &i, "sort", + srw_pdu->u.request->sort.sortKeys); + break; + } if (request->facetList) { Z_FacetList *facet_list = request->facetList; @@ -356,11 +433,24 @@ int yaz_solr_encode_request(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, } else return -1; - name[i] = 0; + + if (srw_pdu->extra_args) + { + Z_SRW_extra_arg *ea = srw_pdu->extra_args; + for (; ea && i < SOLR_MAX_PARAMETERS; ea = ea->next) + { + name[i] = ea->name; + value[i] = ea->value; + i++; + } + } + + name[i++] = 0; + yaz_array_to_uri(&uri_args, encode, name, value); - + hreq->method = "GET"; - + path = (char *) odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + strlen(solr_op) + 4);