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

SavedObjectClient.find multiple types #19231

Merged
merged 14 commits into from
May 24, 2018
Merged

Conversation

kobelb
Copy link
Contributor

@kobelb kobelb commented May 18, 2018

#17426 introduced an includeTypes parameter to the SavedObjects.find, but it was used inconsistently through the SavedObjectClient. It was affecting the score of the documents, wasn't affecting the search query itself and it wasn't being used for sorting.

This PR modifies the SavedObjectsClient.find so that it accepts null, a string, or an array of strings for the type property. Additionally, we're now only searching across known saved object types where we used to be including an incorrect query when searching without specifying a type.

It should be noted, we still don't support sorting without specifying at least one type. Additionally, we only support sorting across multiple types if the field is a "root property". So, currently sorting by "type" or "updatedBy" are the only supported fields. Sorting by "nested" properties led to inconsistent results because we'd create a sort similar to the following:

sort: [
  {'visualize.title': {...} },
  {'savedSearch.title': {...} }
]

where first Visualizations would be returned sorted by title, and then savedSearches would be returned sorted by title.

@kobelb kobelb requested review from tylersmalley and rhoboat May 18, 2018 20:48
@kobelb
Copy link
Contributor Author

kobelb commented May 18, 2018

/cc @chrisronline

@@ -272,7 +272,6 @@ export class SavedObjectsClient {
sortField,
sortOrder,
fields,
includeTypes,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To prevent breaking the saved objects UI upon merging, can we leave this as an optional parameter and merge it with the type parameter? I'll remove it once I update the saved objects UI to stop using it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should've updated all usages of includeTypes to type

@elasticmachine
Copy link
Contributor

💔 Build Failed

@kobelb kobelb force-pushed the saved-object-types branch from 10c1149 to 8572a90 Compare May 21, 2018 12:06
@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@kobelb
Copy link
Contributor Author

kobelb commented May 22, 2018

@tylersmalley @archanid this is ready for review when you get the chance.

const rootProperties = getRootProperties(mappings);
return Object.entries(rootProperties).reduce((acc, [key, value]) => {

// we consider the existence of the properties or type of object to designate that this is an object
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should say "... to designate that this is a type"

Copy link

@rhoboat rhoboat May 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm. I guess we are calling these "root properties objects", so maybe type makes sense? But to me personally, the root properties object is the same thing as a top level type. Maybe saying "... to designate that this is a top level mapping type"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the naming is quite weird. I was trying to keep the way we were parsing the mappings separate from their usage within Kibana's saved objects, which prevented me from naming it getSavedObjectTypes. Perhaps going with a long and somewhat clumsy name of getRootPropertiesThatAreObjectDatatypes is better?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comment wasn't talking about saved objects in particular. I was thinking of the elasticsearch naming, of "top level mapping type" which seems like a common way to describe that thing.

mappings
|-type (_doc)
  |-properties
    |-object datatype (kibana saved object type, sub-type of doc)
    |-field (fields common to all sibling object datatypes)
    |- ...

But ah, there's always the top level _doc type, so everything below it is just some thing, which we call types in Kibana, but which are generically Object Datatypes.

Does that above diagram describe it?

I now think the comment should say ".. that this is an object datatype"

if (Array.isArray(type)) {
const rootField = getProperty(mappings, sortField);
if (!rootField) {
throw Boom.badRequest(`Unable to sort multiple types by field ${sortField}, not a root field`);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message.. Will people know what a "root field" is? If it's not something we say anywhere else, i'd use language that is consistent...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up until this point, we haven't had to leak the way that these objects are mapped to the internal indices to consumers of the SavedObjectsClient yet, so I'm not aware of any existing language besides what we refer to them within the mappings "module" which is as "root properties", perhaps "root properties" would be more clear?

Copy link

@rhoboat rhoboat May 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I do think root properties is clearer. You think of fields and properties as the same thing. I can see that.. but I sort of feel like fields are just anything under the "properties" key that is not an object datatype. But even this usage of "field" isn't totally fool-proof because there's also multi-fields fields, which actually use the key field (https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html), so we're really at a loss for a word to describe a non-multi-field, non object datatype thing that lives in properties.

After thinking more, I'm really not sure if root field or root property is better here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++ for root property instead of root field

@@ -119,5 +192,25 @@ describe('searchDsl/getSortParams', () => {
});
});
});
describe('sortField is root multi-field with multiple types', () => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For these descriptions, maybe say "data type" whenever it's talking about a data type, instead of just "type", which can refer to more things, like mapping types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using "type" in these descriptions, it's referring to the function parameter which is currently named type, so I'm not sure if referring to them as "data type" would provide any more clarity.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough.

Copy link

@rhoboat rhoboat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, the comments about naming are your call.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Copy link
Contributor

@tylersmalley tylersmalley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@tylersmalley
Copy link
Contributor

As a note, we will probably need to figure out how to sort by multiple nested fields without having them grouped. but this is not something which we have a need for yet.

@kobelb
Copy link
Contributor Author

kobelb commented May 24, 2018

As a note, we will probably need to figure out how to sort by multiple nested fields without having them grouped. but this is not something which we have a need for yet.

Agreed, there's potential for us to use Script Based Sorting to accomplish this, but there also might be a more performant way.

@kobelb kobelb merged commit a47348d into elastic:master May 24, 2018
@kobelb kobelb deleted the saved-object-types branch May 24, 2018 11:45
kobelb added a commit to kobelb/kibana that referenced this pull request May 24, 2018
* Making the SavedObjectsClient.find accept a string or string[] for type

* Searching is now filtered to actual types

* Adding multi-type sort

* Changing another use of includeTypes

* Fixing test's reliance on type

* Changing the find route to take type as an array

* Can't sort on type... it's not a property on the object

* Only allowing sorting on multiple types if it's a root property

* Expanding indicator of root property object

* Sorting by type, now that it's allowed and one of the few sort columns

* Adjusting comment

* Throwing better error message
@elasticmachine
Copy link
Contributor

💔 Build Failed

@kobelb kobelb added v7.0.0 v6.4.0 non-issue Indicates to automation that a pull request should not appear in the release notes labels May 24, 2018
kobelb added a commit that referenced this pull request May 24, 2018
* SavedObjectClient.find multiple types (#19231)

* Making the SavedObjectsClient.find accept a string or string[] for type

* Searching is now filtered to actual types

* Adding multi-type sort

* Changing another use of includeTypes

* Fixing test's reliance on type

* Changing the find route to take type as an array

* Can't sort on type... it's not a property on the object

* Only allowing sorting on multiple types if it's a root property

* Expanding indicator of root property object

* Sorting by type, now that it's allowed and one of the few sort columns

* Adjusting comment

* Throwing better error message

* Updating search_dsl error snapshots after changing error message (#19394)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
non-issue Indicates to automation that a pull request should not appear in the release notes v6.4.0 v7.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants