How to add multiple fields for sorting top hits in ElasticSearch Java API? - elasticsearch

I know that ES supports sorting top hits by more than one fields, like sort: ["_score", "datetime"] suggested by this post: https://discuss.elastic.co/t/top-hits-query-with-same-score/107018
But how to do it using Java API?
The AggregationBuilders.topHits().sort() only receives one field as parameter.
Should I use
and SortBuilder as parameter?
If so, SortBuilder asks for a QueryShardContext parameter, which I don't know how to create. I have never used it before. None of the other requests uses this QueryShardContext.
Is there any simple way to do it, like, just pass in an array of fields into sort()?
Thanks in advance!

There are overloaded TopHitsAggregationBuilder.sort() methods, namely one that takes String name, i.e. the name of a field, so you can do it like this:
TopHitsAggregationBuilder thabuilder = AggregationBuilders.topHits("top");
thabuilder.sort("datetime", SortOrder.DESC);
thabuilder.sort("field2", SortOrder.ASC);
...
All the sort calls will add a new sort component to the top-hits aggregation.

Related

Ag-Grid 'agSetColumnFilter' Customization

Can i change the default behaviour of agSetColumnFilter of ag-grid. I can change the filter values by using values: paramter in filterParams. But Since Set Filter performs exact serarch with cell Value so can i update it to Contains search instead of Exact Search.
Yes, you can do it. Under column definition.
{
filter: 'agSetColumnFilter',
filterParams: {
values: ["custom1", "custom2"]
}
Also read about [https://www.ag-grid.com/javascript-grid-server-side-model-filtering/#example-set-filter] to load the values Async.
No, that's not supported. The whole point of the agSetColumnFilter is to match a (hopefully) small set of values contained in a column. If you have so many different values that you need a 'contains' filter, then the setFilter is probably not appropriate anyway.
That said, if you want custom behavior in a filter, that is not accommodated by a standard filter your best is probably to write your own custom filter. The documentation for custom filters can be found at https://www.ag-grid.com/javascript-grid-filter-component/#custom-filter-example

Spring MVC REST API to Filter/Search from Collection

I have a REST service /accounts which returns all the accounts data (Number, Name).
Requirement :
Should Support the below search/filter pattern with any combination of "And" or "OR" rather than retruning the entire collection.
startsWith
endsWith
Contains
Question 1 : Are these below API design correct(RESTful) or any better way to do the same
e.g -
/accounts?name^My Account 123**or**number~ACC1234
(^"==> Starts with , "~"==> ends with)
/accounts?name^My Account 123**and**number~ACC1234
(^"==> Starts with "~"==> ends with)
/accounts?name$ACC123
($ ==> account collection contains ACC123)
Spring Controller:
Planning to get these Filter (Query Parameter) pattern as #RequestParam and have a Regex to parse the pattern and then apply & retrieve it from the data store. The downside is any new filter pattern would need a change in the Controller class.
Question 2: Is there any out of the box features available in Spring 3 to do search / filter from a collection?
Thanks!
From a design perspective, using Query parameters to specify search / filter parameters is fine. However, for more complex cases such as yours, I typically define a new end point, that only deals with searches.
As an example, if my logic for search is strictly "or" and "contains", I would define a book search as such:
GET /books/?author=john&keywords=how%20to%20use%20spring
Here, my API is strictly going to search for books where the author's name contains "john" and the words "how to use spring" appear in the content. The Search logic stays consistent, and the client has no flexibility.
In your case, if the client has the ability to specific their own search criteria, you need to build out a new end point, something like:
POST /books/search
And in the request body, post your own search criteria DSL like name^My Account 123**and**number~ACC1234

Should specific filters be expressed as an explicitly named field, or a generic field with a filter param?

When expressing data filters, via GraphQL, should we be creating explicitly-named fields for that filter or should we be adding a parameter to a more generic list-type field that would apply the filter?
For example, if I've got a field called teams but I want to provide the ability to filter the data, provided by teams, down to only the teams who are active (versus inactive), should I expose that filter via GraphQL as a param on the teams field, or should I create a new field called activeTeams?
I'm thinking the clearly, explicitly named fields might scale better and be less confusing in the long run because there won't be questions about how params works when paired with each other, etc.
I wanted to get feedback on how maybe Facebook approaches this, or how others are doing so.
You should add the filter as a param on the teams field as this is the more scalable approach. Introducing a new filter means only a single parameter needs adding. Whereas the multiple-fields approach requires an exponential number of fields for each possible combination.
Don't forget that you can also alias fields on the client if you wish to fetch multiple queries of teams within the same component:
query on Viewer {
activeTeams: teams(active: true) { ... }
inactiveTeams: teams(active: false) { ... }
}

Is there a way to search for transactions by custom field?

I store specific custom field for each transaction. I'd like to conduct a search by this field. I wouldn't like to retrieve too many transactions (can filter by payment method id, but still) and iterate through them on application side. So, I read a documentation, didn't find an ability to search by custom field (only by predefined). I didn't try it out, but probably it's possibly to do so by following the same pattern like
var stream = gateway.transaction.search(function (search) {
search.myCustomField().is("custom_field_value");
// or search.customFields.myCustomField().is("custom_field_value");
});
Thanks in advance
I work as a developer for Braintree. Searching on custom fields is not supported at this time. You can see all of the searchable transaction attributes listed here.
If you would like to discuss alternatives, I recommend emailing our support team at support#braintreepayments.com to see if there is another method to achieve what you are trying to do.

OData $filter substringof applied to a list of strings

I have an ASP.NET Web API Controller that exposes an IQueryable(Of String) - which is a list of descriptions. These fields can be in the order of tens of thousands, thus I use $top and $skip to only get a chunk of it - that works fine.
Now I am trying to filter these results, through the OData substringof('mydesc',Property) filter. As you can see, it requires for me to pass in a Property name on which to filter. However, since I'm returning a list of strings, I don't actually have any properties to filter on.
This causes the server to return errors like
No property or field 'tostring' exists in type 'String' - when called with $filter=substringof('asd',tostring).
If I change the call to $filter=substringof('asd',''), no errors are thrown, but no results either.
My question is, can I somehow format the $filter operator to find substrings within my list of strings, without looking for a property/field, or am I going to have to declare a class with a single property, just to enable filtering?
Things have changed since the last time I answered this. OData V3 has support for querying collection of primitives using '$it'. Asp.net Web API supports this syntax as well. For example, in your controller you can return IQueryable<string> and send a request like
$filter=substring('mydesc', $it) or
$filter=length($it) ge 5
etc. You can also expose collections of other primitives like IQueryable etc.
unfortunately declaring a class with a single property seems to be the only solution that I can think of. OData $filter doesn't have any support for something like the this parameter in C#
another less obvious approach is to expose a computed concatenated value representing the list, substringof could then be used to query the list as a single property value

Resources