Exemplo n.º 1
0
Arquivo: query.py Projeto: N03/invenio
def get_affected_records(spec=None, search_pattern=None):
    """Get list of affected records.

    :param spec: The record spec.
    :param search_pattern: The search pattern.
    :returns: An iterator to lazily find results.
    """
    # spec       pattern    query
    # ---------- ---------- -------
    # None       None       None
    # None       Y          Y
    # X          None       X
    # X          ''         X
    # X          Y          X OR Y

    if spec is None and search_pattern is None:
        raise StopIteration

    queries = []

    if spec is not None:
        queries.append(Q('match', **{'_oai.sets': spec}))

    if search_pattern:
        queries.append(Query(search_pattern).query.accept(ElasticSearchDSL()))

    search = OAIServerSearch(
        index=current_app.config['OAISERVER_RECORD_INDEX'], ).query(
            Q('bool', should=queries))

    for result in search.scan():
        yield result.meta.id
Exemplo n.º 2
0
def index_collection_percolator(name, dbquery):
    """Create an elasticsearch percolator for a given query."""
    from invenio_search.api import Query
    from invenio_search.walkers.elasticsearch import ElasticSearchDSL
    es.index(index='records',
             doc_type='.percolator',
             body={'query': Query(dbquery).query.accept(ElasticSearchDSL())},
             id=name)
Exemplo n.º 3
0
def index_collection_percolator(name, dbquery):
    """Create an elasticsearch percolator for a given query."""
    indices = set(cfg["SEARCH_ELASTIC_COLLECTION_INDEX_MAPPING"].values())
    indices.add(cfg['SEARCH_ELASTIC_DEFAULT_INDEX'])
    for index in indices:
        es.index(
            index=index,
            doc_type='.percolator',
            body={'query': Query(dbquery).query.accept(ElasticSearchDSL())},
            id=name)
 def setUp(self):
     self.converter = ElasticSearchDSL()
     self.converter.keyword_dict = {"foo": ["test1", "test2"]}
Exemplo n.º 5
0
def search(collection, p, of, ot, so, sf, sp, rm, rg, jrec):
    """Render search page."""
    if 'action_browse' in request.args \
            or request.args.get('action', '') == 'browse':
        return browse()

    if 'c' in request.args and len(request.args) == 1 \
            and len(request.args.getlist('c')) == 1:
        return redirect(url_for('.collection', name=request.args.get('c')))

    if 'f' in request.args:
        args = request.args.copy()
        args['p'] = "{0}:{1}".format(args['f'], args['p'])
        del args['f']
        return redirect(url_for('.search', **args))

    # fix for queries like `/search?p=+ellis`
    p = p.strip().encode('utf-8')

    response = Query(p).search(collection=collection.name)
    response.body.update({
        'size': int(rg),
        'from': jrec-1,
        'aggs': cfg['SEARCH_ELASTIC_AGGREGATIONS'].get(
            collection.name.lower(), {}
        )
    })

    if sf in cfg['SEARCH_ELASTIC_SORT_FIELDS']:
        so = so if so in ('asc', 'desc') else ''
        sorting = {
            'sort': {
                sf: {
                    'order': so
                }
            }
        }
        response.body.update(sorting)

    # FIXME refactor to separate search hook
    filtered_facets = ''
    from invenio_search.walkers.elasticsearch import ElasticSearchDSL
    if 'post_filter' in request.values and request.values['post_filter']:
        parsed_post_filter = Query(request.values.get('post_filter'))
        post_filter = parsed_post_filter.query.accept(
            ElasticSearchDSL()
        )
        response.body['query'] = {
            "filtered": {
                'query': response.body['query'],
                'filter': post_filter
            }
        }
        # extracting the facet filtering
        from invenio_search.walkers.facets import FacetsVisitor
        filtered_facets = parsed_post_filter.query.accept(
            FacetsVisitor()
        )
        # sets cannot be converted to json. use facetsVisitor to convert them
        # to lists
        filtered_facets = FacetsVisitor.jsonable(filtered_facets)
    else:
        # Save current query and number of hits in the user session
        session_key = 'last-query' + p + collection.name
        if not session.get(session_key):
            session[session_key] = {}

        session[session_key] = {
            "p": p,
            "collection": collection.name,
            "number_of_hits": len(response),
            "timestamp": datetime.datetime.utcnow()
        }

    number_of_hits = len(response)

    if number_of_hits and jrec > number_of_hits:
        args = request.args.copy()
        args['jrec'] = 1
        return redirect(url_for('.search', **args))

    pagination = Pagination((jrec-1) // rg + 1, rg, number_of_hits)

    ctx = dict(
        facets={},  # facets.get_facets_config(collection, qid),
        filtered_facets=filtered_facets,
        response=response,
        rg=rg,
        ot=ot,
        pagination=pagination,
        collection=collection,
    )

    # TODO add search services
    # TODO add external collection search

    return response_formated_records(response.records(), of, **ctx)
Exemplo n.º 6
0
def search(collection, p, of, ot, so, sf, sp, rm, rg, jrec):
    """Render search page."""
    if 'action_browse' in request.args \
            or request.args.get('action', '') == 'browse':
        return browse()

    if 'c' in request.args and len(request.args) == 1 \
            and len(request.args.getlist('c')) == 1:
        return redirect(url_for('.collection', name=request.args.get('c')))

    if 'f' in request.args:
        args = request.args.copy()
        args['p'] = "{0}:{1}".format(args['f'], args['p'])
        del args['f']
        return redirect(url_for('.search', **args))

    # fix for queries like `/search?p=+ellis`
    p = p.strip().encode('utf-8')

    collection_breadcrumbs(collection)

    response = Query(p).search(collection=collection.name)
    response.body.update({
        'size': int(rg),
        'from': jrec-1,
        'aggs': {
            "collection": {"terms": {"field": "_collections"}},
            "author": {"terms": {"field": "authors.raw"}},
        },
    })

    # FIXME refactor to separate search hook
    filtered_facets = ''
    from invenio_search.walkers.elasticsearch import ElasticSearchDSL
    if 'post_filter' in request.values:
        parsed_post_filter = Query(request.values.get('post_filter'))
        post_filter = parsed_post_filter.query.accept(
            ElasticSearchDSL()
        )
        response.body['post_filter'] = post_filter
        # extracting the facet filtering
        from invenio_search.walkers.facets import FacetsVisitor
        filtered_facets = parsed_post_filter.query.accept(
            FacetsVisitor()
        )
        # sets cannot be converted to json. use facetsVisitor to convert them to
        # lists
        filtered_facets = FacetsVisitor.jsonable(filtered_facets)

    if len(response) and jrec > len(response):
        args = request.args.copy()
        args['jrec'] = 1
        return redirect(url_for('.search', **args))

    pagination = Pagination((jrec-1) // rg + 1, rg, len(response))

    ctx = dict(
        facets={},  # facets.get_facets_config(collection, qid),
        filtered_facets=filtered_facets,
        response=response,
        rg=rg,
        create_nearest_terms_box=lambda: _("Try to modify the query."),
        easy_search_form=EasySearchForm(csrf_enabled=False),
        ot=ot,
        pagination=pagination,
        collection=collection,
    )

    # TODO add search services
    # TODO add external collection search

    return response_formated_records(response.records(), of, **ctx)