-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Add "Popular fields" to Lens as part of the "Unified Field List" initiative #147704
Conversation
Pinging @elastic/kibana-visualizations @elastic/kibana-visualizations-external (Team:Visualizations) |
@elasticmachine merge upstream |
💚 Build Succeeded
Metrics [docs]Async chunks
Unknown metric groupsESLint disabled in files
ESLint disabled line counts
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: cc @VladLasitsa |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would propose a small refactoring of the populaizeField
function to do the actual work only in success case.
Found also a bug: when Combining
two or more fields (using Top values
multi-terms) the popularized function is not called.
I wonder if it makes sense to fire off a request every time one user uses a field. Would it be best to batch them by some longer time slot somehow? Do not think this is a vital information to have.
if (!indexPatternId || !capabilities?.indexPatterns?.save) return; | ||
const dataView = await dataViewsService.get(indexPatternId); | ||
const field = dataView.fields.getByName(fieldName); | ||
if (!field) { | ||
return; | ||
} | ||
|
||
field.count++; | ||
|
||
const refreshIndexPatternsListArgs = { | ||
activeDatasources: Object.keys(datasourceStates).reduce( | ||
(acc, datasourceId) => ({ | ||
...acc, | ||
[datasourceId]: datasourceMap[datasourceId], | ||
}), | ||
{} | ||
), | ||
indexPatternId, | ||
indexPatternService, | ||
indexPatternsCache, | ||
}; | ||
|
||
if (!dataView.isPersisted()) { | ||
refreshIndexPatternsList(refreshIndexPatternsListArgs); | ||
return; | ||
} | ||
|
||
// Catch 409 errors caused by user adding columns in a higher frequency that the changes can be persisted to Elasticsearch | ||
try { | ||
await dataViewsService.updateSavedObject(dataView, 0, true); | ||
refreshIndexPatternsList(refreshIndexPatternsListArgs); | ||
// eslint-disable-next-line no-empty | ||
} catch {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would refactor a bit here to do the async work only in case of success for a persisted dataView:
if (!indexPatternId || !capabilities?.indexPatterns?.save) return; | |
const dataView = await dataViewsService.get(indexPatternId); | |
const field = dataView.fields.getByName(fieldName); | |
if (!field) { | |
return; | |
} | |
field.count++; | |
const refreshIndexPatternsListArgs = { | |
activeDatasources: Object.keys(datasourceStates).reduce( | |
(acc, datasourceId) => ({ | |
...acc, | |
[datasourceId]: datasourceMap[datasourceId], | |
}), | |
{} | |
), | |
indexPatternId, | |
indexPatternService, | |
indexPatternsCache, | |
}; | |
if (!dataView.isPersisted()) { | |
refreshIndexPatternsList(refreshIndexPatternsListArgs); | |
return; | |
} | |
// Catch 409 errors caused by user adding columns in a higher frequency that the changes can be persisted to Elasticsearch | |
try { | |
await dataViewsService.updateSavedObject(dataView, 0, true); | |
refreshIndexPatternsList(refreshIndexPatternsListArgs); | |
// eslint-disable-next-line no-empty | |
} catch {} | |
if (!indexPatternId || !capabilities?.indexPatterns?.save) return; | |
const lensDataView = indexPatternsCache[indexPatternId]; | |
if (!lensDataView.getFieldByName(fieldName)) { | |
return; | |
} | |
if (lensDataView.isPersisted) { | |
// Catch 409 errors caused by user adding columns in a higher frequency that the changes can be persisted to Elasticsearch | |
try { | |
const dataView = await dataViewsService.get(indexPatternId); | |
const field = dataView.fields.getByName(fieldName); | |
if (field) { | |
field.count++; | |
await dataViewsService.updateSavedObject(dataView, 0, true); | |
} | |
// eslint-disable-next-line no-empty | |
} catch {} | |
} | |
const refreshIndexPatternsListArgs = { | |
activeDatasources: Object.keys(datasourceStates).reduce( | |
(acc, datasourceId) => ({ | |
...acc, | |
[datasourceId]: datasourceMap[datasourceId], | |
}), | |
{} | |
), | |
indexPatternId, | |
indexPatternService, | |
indexPatternsCache, | |
}; | |
refreshIndexPatternsList(refreshIndexPatternsListArgs); |
It is a little bit more verbose but it saves some work for adHoc dataviews
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you @dej611, I will update my function. About batch requests I don't think that is a good idea. I call refreshIndexPatternsList
here to show correct state of fields after updating popularity. In you proposal we should call refreshIndexPatternsList
after some timeout which lead to showing correct list of popular fields with delay.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dej611, also for adHoc dataviews we also should use this field.count++;
not only for usual dataviews.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's wait for the main decision on the feature first.
But for the adHoc I think that operating on the cached version should be ok, no?
@dej611 one important note on this feature is that we want the counter to initialize only for actions made by the fields list.
|
I've already added this info in PR description:) |
But combine is a drag and drop action 🤔 |
Yes I have tried to convince against this one and take some time to think about it more but it seems that it has been decided |
Besides the specific implementation I have few questions regarding this feature: what value is it going to bring to the user?
Just few thoughts for a discussion here. cc @stratoula @ninoslavmiskovic |
Hm, but as I understand |
I couldn't agree more @dej611. I will try to raise it again! |
@dej611, Some thinking:
If we separate counter, what should we do with
About these two: I have used the same approach as in Discover (see here |
@VladLasitsa @dej611 let's pause it for now. I pinged Tim to revisit because 3 engineers disagree with this feature and I think we should re-evaluate. |
Moving this to draft as we decided to discuss more. |
I have setup a meeting in the new year,so that we can align. I will go through "what we know today" regarding popular fields, what we aim to learn from market feedback and what user problems we are aiming to solve, when added to Lens. The aim is to bring clarity and most importantly provide value to the users, like it does in Discover. |
Since I will finish work on the project this year, removed my assignment, feel free to continue working here or close this PR. |
Yes, I do agree. In Lens it takes too much screen space, and when there are just a few popular fields, a new field that was just popularized is eating up vertical space in "realtime" Users can collapse the field sections, but it's not remembered - we should build in functionality to remember the collapse state in e.g. localStorage. FYI @jughosta because it would be a neat unified field list feature
Yes, I also agree that different use cases need different field stats. And the pattern of increasing the statistics directly in the data view saved object I would consider has legacy behavior. The statistics isn't even accurate because of:
I think popular fields make sense to help the user find his frequently used fields in a quicker way. This may vary by application and also by user type. What could be a solution to a) still use the counter in the data views saved object b) add statistics by user / application ? For example we could still use the counter of the data view saved object, so admins could use those to provide base values. And then we would collect the the increments of the the counter values by application in localStorage. Then Lens/Discover would have different statistics based on a users field selection. This would be the simplest solution that comes to my mind (and we should aim for simplicity) FYI @mattkime because we chatted about the field popularization a while ago, you mentioned to could be collected in a separate saved object ... a solution like this would also provide a way to collect different statistic / application ... however it sounds like more effort
I do agree about the "dancing", but I think it's also fine to limit the popularity to those fields the user interacted with in the sidebar field selection.
You mean the 409 ignorance, when clicking faster than Elasticsearch allows, right? |
I would be ok, to me, to record user interactions as long as all add/remove operation are used. But this is not the case here, as only "some" adding flows are tracked and no removal.
Yes. |
I do agree, when the user is interacting with the interface, popularity increase should not change the interface. And updating the score not immediately, in a patched way on certain events would be a good way to get rid of the 409s and get better statistics. One thing I've always been wondering, why should fields, when they are removed get more "popular"?
Thx Great work @jughosta BTW for already implementing state of the sections in localStorage 👍 |
@kertal tbh I was wondering the same thing. Following the code in Discover I see that we popularizeField when:
but not when I am doing other things with the fields such as:
While I strongly believe that the popular fields in Lens should be fields that are actually used a lot on saved visualizations I think that we might consider re-thinking what popular fields mean in discover too. |
Summary
Closes: #145687
Added "Popular fields" to Lens.
The field will appear in 'popular fields' section in following scenarios:
popularity
for field in dataview management sectiondiscover
(as Lens and Discover use the same popularity counter if user add field in discover, that field also will appear in popular section in Lens)