Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search component does not allow you to use FacetValue with authority operator #368

Closed
atarix83 opened this issue Mar 7, 2019 · 4 comments · Fixed by #952
Closed

Search component does not allow you to use FacetValue with authority operator #368

atarix83 opened this issue Mar 7, 2019 · 4 comments · Fixed by #952
Labels
bug component: Discovery related to discovery search or browse system

Comments

@atarix83
Copy link
Contributor

atarix83 commented Mar 7, 2019

The actual implementation does not allow you to use FacetValue with authority operator, that are required to implement MyDSpace.

Here an example of FacetValue with authority operator

            {
                "label": "To do",
                "count": 202,
                "type": "discover",
                "_links": {
                    "search": {
                        "href": "http://localhost:8080/spring-rest/api/discover/search/objects?f.namedresourcetype=workspace,authority"
                    }
                }
            },

the correct search query to filter the result set with this facet value should use f.namedresourcetype=workspace,authority but because the actual implementation of the search when I click on the link of the that facet value the query is built with f.namedresourcetype=To do,query

To resolve this problem Search component should find a way to use the ‘search’ hard-link property from FacetValue to build search query

@artlowel
Copy link
Member

By now I've had a chance to look into why these links aren't used yet, and the reason is that search is currently designed in the following way:

  • everything you can interact with changes the client url
  • there is one piece of code, that watches the client url, and queries the rest api when it changes.
  • when the rest response comes back, the results, and facet options are updated.

The main reasons for doing it this way are:

  • If most search controls are <a> tags that update the URL, and that URL change triggers a content change.
    • That's very good for accessibility; it's exactly the way a static site would work, and it can work without javascript enabled.
    • It also ensures that the entire state of the page is represented in the URL, so whatever you're looking at, you can share the URL with someone else, and they'll see the same thing.
  • Most interactive elements in the search UI can't work using HAL links atm. e.g.
    • You can't create a hal link for a filter query entered by the user at the bottom of a facet in the sidebar
    • or for a date change (dragging the slider, or changing the date by a year for example)
    • or for a change to the sort options, or number of results per page
  • So if we would use the hal links for filtervalues to fetch the rest response, then we would have some instances where the client URL would have to change as a consequence of a rest response, and some where the rest api would have to be called as a consequence of a client URL change. It would make things a lot more complex, and increase the chances of infinite loops where following a HAL link triggers a client URL update, which in turn triggers a rest call which triggers a client URL update, etc.
  • Currently the HAL links for facetValues don't contain things like sort params for example, so using those links would mean the user would lose their pagination settings.

I do agree that the current way of working is not ideal; we need too much logic in the UI to figure out what needs to change to the rest call for each search control.

E.g. for dates, the UI needs to work using a start and an end date, because you can change them independently, but then we need to know how to parse that start and enddate from the label, and we need to know how to put it back together to query the server. Parsing the label to get the values isn't a good idea, because you don't want to have to add custom code to the UI every time the label doesn't match the value to send to the server.

So instead of having the server dictate exactly what the UI should do (hal links), or not using server input at all (the current way), perhaps we can find a way in between. If the server were to add a property that only contains how to change the current facetValue, and not everything else, the client can use those as building blocks to construct the query on its own, without having to hardcode too much details about it.

If we include a simple templating system it can work for things with variable inputs as well. E.g.:

In the filter below, queryParam was added

    {
      "filter": "dateIssued",
      "hasFacets": true,
      "type": "date",
      "queryParam": "f.dateIssued=[${start} TO ${end}],${operator}",
      "operators": [
        {
          "operator": "equals"
        },
        {
          "operator": "notequals"
        },
        {
          "operator": "authority"
        },
        {
          "operator": "notauthority"
        },
        {
          "operator": "contains"
        },
        {
          "operator": "notcontains"
        }
      ],
      "openByDefault": false
    }

In the facetValue below, start, end and operator were added

{
          "label" : "1950 - 1959",
          "start": 1950,
          "end": 1959,
          "operator": "equals",
          "count" : 27,
          "type" : "discover",
          "_links" : {
            "search" : {
              "href" : "https://rest.api/discover/search/objects?f.dateIssued=[1950 TO 1959],equals"
            }
          }
        }

@abollini
Copy link
Member

From the above comment I recognise two tasks on the REST side:

  1. the search implementation has a bug: the sorting should be included in the link exposed by the facet values. Please note that it doesn't make sense to keep the pagination offset when the user is narrowing his research, so I don't see other missing information on the facet value's link other than the sorting
  2. we need to support the URI Template, the good news is that it is described by the HAL specification https://tools.ietf.org/html/draft-kelly-json-hal-08#section-5.2 so we "only" need to implement it. The template must be provided within a link something like that
"facets": [
      {
        "name": "author",
        "facetType": "text",
        "facetLimit": 5,
        "minValue": "Fellinger, Michael R",
        "maxValue": "Wemmer",
        "_links": {
          "next": {
            "href": ".../api/discover/facets/author?query=xxxx&page=1&size=5"
          },
          "self": {
            "href": ".../api/discover/facets/author?query=xxxx&"
          },
          "search": {
            "href": ".../api/discover/search/objects?query=xxxx&f.author={authorvalue},{operator}&sort={sortField,order}"
          }
        },

The following JIRA ticket have been created
https://jira.duraspace.org/browse/DS-4195
https://jira.duraspace.org/browse/DS-4196

@artlowel
Copy link
Member

@abollini, you mentioned in the meeting on 2019-03-21 that there was a way of using HAL links, where we wouldn't have to lose the advantage of having the UI components change only the URL, and responding to the URL change by querying the backend. Could you elaborate on that?

  1. the search implementation has a bug: the sorting should be included in the link exposed by the facet values. Please note that it doesn't make sense to keep the pagination offset when the user is narrowing his research, so I don't see other missing information on the facet value's link other than the sorting

The number of results per page is also missing information.

@abollini
Copy link
Member

@atarix83 help me to understood better the issue on the angular side and unfortunately I don't think it is something that can be quickly fixed with the current implementation. You can use for sure the HAL link to refresh the page using the data coming for a fresh REST call but it will be complicated to restore the state of the application using the current URL structure.
I think that you should use a completely different approach and only make a single rest call to update the result (../objects) instead than retrieve each single facet box with a separate call. If you do that essentially you only need to put the search REST API in a single parameter without care about its structure. This approach will also produce performance improvements as it will save a lot of additional calls.
The current search contract doesn't allow you to paginate the facet over the objects endpoint but I don't think that this will be an issue as you will use the facet endpoint to move next and back. To restore the state of the application from the URL you should use the "big search url" parameter for the first query, and additional parameter to fill the self url of the returned facet using the url template mechanism discussed in #368 (comment)

Until the url template mechanism will be introduced, if you go to change the implementation to use the single big url, the only issue will be to loss the state of the facet boxes when sharing an angular UI... honestly I think it is a minor bug, we could live with that also in a final release

@tdonohue tdonohue added the bug label Jan 6, 2020
@tdonohue tdonohue added the component: Discovery related to discovery search or browse system label Apr 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug component: Discovery related to discovery search or browse system
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants