Example #1
0
def solrSearchResults(request=None, **keywords):
    """ perform a query using solr after translating the passed in
        parameters with portal catalog semantics """
    search = queryUtility(ISearch)
    config = queryUtility(ISolrConnectionConfig)
    if request is None:
        # try to get a request instance, so that flares can be adapted to
        # ploneflares and urls can be converted into absolute ones etc;
        # however, in this case any arguments from the request are ignored
        request = getattr(getSite(), 'REQUEST', None)
        args = deepcopy(keywords)
    elif IHTTPRequest.providedBy(request):
        args = deepcopy(request.form)  # ignore headers and other stuff
        args.update(keywords)       # keywords take precedence
    else:
        assert isinstance(request, dict), request
        args = deepcopy(request)
        args.update(keywords)       # keywords take precedence
        # if request is a dict, we need the real request in order to
        # be able to adapt to plone flares
        request = getattr(getSite(), 'REQUEST', args)
    if 'path' in args and 'navtree' in args['path']:
        raise FallBackException     # we can't handle navtree queries yet
    use_solr = args.get('use_solr', False)  # A special key to force Solr
    if not use_solr and config.required:
        required = set(config.required).intersection(args)
        if required:
            for key in required:
                if not args[key]:
                    raise FallBackException
        else:
            raise FallBackException
    schema = search.getManager().getSchema() or {}
    params = cleanupQueryParameters(extractQueryParameters(args), schema)
    languageFilter(args)
    prepareData(args)
    mangleQuery(args, config, schema)
    query = search.buildQuery(**args)
    if query != {}:
        optimizeQueryParameters(query, params)
        __traceback_info__ = (query, params, args)
        response = search(query, **params)
    else:
        return SolrResponse()
    def wrap(flare):
        """ wrap a flare object with a helper class """
        adapter = queryMultiAdapter((flare, request), IFlare)
        return adapter is not None and adapter or flare
    results = response.results()
    for idx, flare in enumerate(results):
        flare = wrap(flare)
        for missing in set(schema.stored).difference(flare):
            flare[missing] = MV
        results[idx] = wrap(flare)
    padResults(results, **params)           # pad the batch
    return response
Example #2
0
def solrSearchResults(request=None, **keywords):
    """ perform a query using solr after translating the passed in
        parameters with portal catalog semantics """
    search = queryUtility(ISearch)
    config = queryUtility(ISolrConnectionConfig)
    if request is None:
        # try to get a request instance, so that flares can be adapted to
        # ploneflares and urls can be converted into absolute ones etc;
        # however, in this case any arguments from the request are ignored
        request = getattr(getSite(), 'REQUEST', None)
        args = deepcopy(keywords)
    elif IHTTPRequest.providedBy(request):
        args = deepcopy(request.form)  # ignore headers and other stuff
        args.update(keywords)       # keywords take precedence
    else:
        assert isinstance(request, dict), request
        args = deepcopy(request)
        args.update(keywords)       # keywords take precedence
        # if request is a dict, we need the real request in order to
        # be able to adapt to plone flares
        request = getattr(getSite(), 'REQUEST', args)
    if 'path' in args and 'navtree' in args['path']:
        raise FallBackException     # we can't handle navtree queries yet
    use_solr = args.get('use_solr', False)  # A special key to force Solr
    if not use_solr and config.required:
        required = set(config.required).intersection(args)
        if required:
            for key in required:
                if not args[key]:
                    raise FallBackException
        else:
            raise FallBackException
    schema = search.getManager().getSchema() or {}
    params = cleanupQueryParameters(extractQueryParameters(args), schema)
    languageFilter(args)
    prepareData(args)
    mangleQuery(args, config, schema)
    query = search.buildQuery(**args)
    if query != {}:
        optimizeQueryParameters(query, params)
        __traceback_info__ = (query, params, args)
        response = search(query, **params)
    else:
        return SolrResponse()
    def wrap(flare):
        """ wrap a flare object with a helper class """
        adapter = queryMultiAdapter((flare, request), IFlare)
        return adapter is not None and adapter or flare
    results = response.results()
    for idx, flare in enumerate(results):
        flare = wrap(flare)
        for missing in set(schema.stored).difference(flare):
            flare[missing] = MV
        results[idx] = wrap(flare)
    padResults(results, **params)           # pad the batch
    return response
 def optimize(**params):
     query = dict(a='a:23', b='b:42', c='c:(23 42)')
     optimizeQueryParameters(query, params)
     return query, params
 def optimize(**params):
     query = dict(a="a:23", b="b:42", c="c:(23 42)")
     optimizeQueryParameters(query, params)
     return query, params
Example #5
0
    def buildQueryAndParameters(self, default=None, **args):
        """ helper to build a querystring for simple use-cases """
        schema = self.getManager().getSchema() or {}

        params = subtractQueryParameters(args)
        params = cleanupQueryParameters(params, schema)
        config = self.getConfig()

        prepareData(args)
        mangleQuery(args, config, schema)

        logger.debug('building query for "%r", %r', default, args)
        schema = self.getManager().getSchema() or {}
        defaultSearchField = getattr(schema, 'defaultSearchField', None)
        args[None] = default
        query = {}

        for name, value in sorted(args.items()):
            field = schema.get(name or defaultSearchField, None)
            if field is None or not field.indexed:
                logger.info(
                    'dropping unknown search attribute "%s" '
                    ' (%r) for query: %r', name, value, args
                )
                continue
            if isinstance(value, bool):
                value = str(value).lower()
            elif not value:     # solr doesn't like empty fields (+foo:"")
                if not name:
                    continue
                logger.info(
                    'empty search term form "%s:%s", aborting buildQuery' % (
                        name,
                        value
                    )
                )
                return {}, params
            elif field.class_ == 'solr.BoolField':
                if not isinstance(value, (tuple, list)):
                    value = [value]
                falses = '0', 'False', MV
                true = lambda v: bool(v) and v not in falses
                value = set(map(true, value))
                if not len(value) == 1:
                    assert len(value) == 2      # just to make sure
                    continue                    # skip when "true or false"
                value = str(value.pop()).lower()
            elif isinstance(value, (tuple, list)):
                # list items should be treated as literals, but
                # nevertheless only get quoted when necessary
                value = '(%s)' % ' OR '.join(map(quote_iterable_item, value))
            elif isinstance(value, set):        # sets are taken literally
                if len(value) == 1:
                    query[name] = ''.join(value)
                else:
                    query[name] = '(%s)' % ' OR '.join(value)
                continue
            elif isinstance(value, basestring):
                if field.class_ == 'solr.TextField':
                    if isWildCard(value):
                        value = prepare_wildcard(value)
                    value = quote(value, textfield=True)
                    # if we have an intra-word hyphen, we need quotes
                    if '\\-' in value or '\\+' in value:
                        if value[0] != '"':
                            value = '"%s"' % value
                else:
                    value = quote(value)
                if not value:   # don't search for empty strings, even quoted
                    continue
            else:
                logger.info(
                    'skipping unsupported value "%r" (%s)', value, name
                )
                continue
            if name is None:
                if value and value[0] not in '+-':
                    value = '+%s' % value
            else:
                value = '+%s:%s' % (name, value)
            query[name] = value
        logger.debug('built query "%s"', query)

        if query:
            optimizeQueryParameters(query, params)
        return query, params
Example #6
0
 def optimize(**params):
     query = dict(a='a:23', b='b:42', c='c:(23 42)')
     optimizeQueryParameters(query, params)
     return query, params
 def optimize(**params):
     query = dict(a="a:23", b="b:42", c="c:(23 42)")
     optimizeQueryParameters(query, params)
     return query, params