jenkins-bot has submitted this change and it was merged. Change subject: Add autocomplete to search satisfaction schema ......................................................................
Add autocomplete to search satisfaction schema * Adds a 'source' field distinguishing events as coming from autocomplete or full text search. * Recreate all full text events for autocomplete * Drop 'searchToken' field from schema, due to sampling of top level sessions it did not provide any useful information. Depends-On: Idae51bf73039ed92c868cb5a0632302843313717 Depends-On: Iec7171fcf301f1659d852afa87ce271f468177c1 Bug: T125915 Change-Id: I5438373ed0c53ff524aea4b0548cd850c7e00e92 --- M extension.json M modules/ext.wikimediaEvents.searchSatisfaction.js 2 files changed, 105 insertions(+), 21 deletions(-) Approvals: Bearloga: Looks good to me, but someone else must approve MaxSem: Looks good to me, approved JGirault: Looks good to me, but someone else must approve jenkins-bot: Verified diff --git a/extension.json b/extension.json index 4841f5c..0eb8d3d 100644 --- a/extension.json +++ b/extension.json @@ -101,7 +101,7 @@ "schema.TestSearchSatisfaction2": { "class": "ResourceLoaderSchemaModule", "schema": "TestSearchSatisfaction2", - "revision": 14098806 + "revision": 15357244 }, "schema.GeoFeatures": { "class": "ResourceLoaderSchemaModule", diff --git a/modules/ext.wikimediaEvents.searchSatisfaction.js b/modules/ext.wikimediaEvents.searchSatisfaction.js index b8575db..cc8575c 100644 --- a/modules/ext.wikimediaEvents.searchSatisfaction.js +++ b/modules/ext.wikimediaEvents.searchSatisfaction.js @@ -25,7 +25,7 @@ return; } - var search, session, + var search, autoComplete, session, isSearchResultPage = mw.config.get( 'wgIsSearchResultPage' ), uri = new mw.Uri( location.href ), checkinTimes = [ 10, 20, 30, 40, 50, 60, 90, 120, 150, 180, 210, 240, 300, 360, 420 ], @@ -49,6 +49,10 @@ } search = initFromWprov( 'srpw1_' ); + autoComplete = initFromWprov( 'acrw1_' ); + // with no position appended indicates the user submitted the + // autocomplete form. + autoComplete.cameFromAutocomplete = uri.query.wprov === 'acrw1'; // Cleanup the location bar in supported browsers. if ( uri.query.wprov && window.history.replaceState ) { @@ -126,14 +130,6 @@ if ( !session.set( 'sessionId', randomToken() ) ) { return false; } - } - - if ( session.get( 'token' ) === null ) { - if ( !session.set( 'token', randomToken() ) ) { - return false; - } - } else { - session.refresh( 'token' ); } // Unique token per page load to know which events occured @@ -230,12 +226,14 @@ setTimeout( action, 1000 * timeout ); } - function genLogEventFn( session ) { + function genLogEventFn( source, session ) { return function ( action, extraData ) { var scrollTop = $( window ).scrollTop(), evt = { // searchResultPage, visitPage or checkin action: action, + // source of the action, either search or autocomplete + source: source, // identifies a single user performing searches within // a limited time span. searchSessionId: session.get( 'sessionId' ), @@ -247,9 +245,9 @@ // identifies if a user has scrolled the page since the // last event scroll: scrollTop !== lastScrollTop, - // identifies a single user over a 24 hour timespan, - // allowing to tie together multiple search sessions - searchToken: session.get( 'token' ) + // mediawiki session id to correlate with other schemas, + // such as QuickSurvey + mwSessionId: mw.user.sessionId() }; lastScrollTop = scrollTop; @@ -279,7 +277,7 @@ * @param {SessionState} session */ function setupSearchTest( session ) { - var logEvent = genLogEventFn( session ); + var logEvent = genLogEventFn( 'fulltext', session ); if ( isSearchResultPage ) { // When a new search is performed reset the session lifetime. @@ -306,15 +304,101 @@ } /** - * Logic starts here. + * Sets up the autocomplete search test. + * + * It will log events and will put an attribute on some links + * to track user satisfaction. + * + * @param {SessionState} session */ - if ( isSearchResultPage || search.cameFromSearch ) { - $( document ).ready( function () { - session = new SessionState(); - if ( session.get( 'enabled' ) ) { - setupSearchTest( session ); + function setupAutocompleteTest( session ) { + var logEvent = genLogEventFn( 'autocomplete', session ); + + if ( autoComplete.cameFromSearch ) { + logEvent( 'visitPage', { + position: autoComplete.resultPosition + } ); + interval( checkinTimes, function ( checkin ) { + logEvent( 'checkin', { + checkin: checkin + } ); + } ); + } + + mw.trackSubscribe( 'mediawiki.searchSuggest', function ( topic, data ) { + if ( data.action === 'impression-results' ) { + // When a new search is performed reset the session lifetime. + session.refresh( 'sessionId' ); + + // run every time an autocomplete result is shown + logEvent( 'searchResultPage', { + hitsReturned: data.numberOfResults, + query: data.query, + inputLocation: data.inputLocation, + autocompleteType: data.resultSetType + } ); + } else if ( data.action === 'render-one' ) { + // run when rendering anchors for suggestion results. Attaches a wprov + // to the link so we know when the user arrives they came from autocomplete + // and what position they clicked. + data.formData.linkParams.wprov = autoComplete.wprovPrefix + data.index; } } ); } + /** + * Delay session initialization as late in the + * process as possible, but only do it once. + * + * @param {Function} fn + */ + function setup( fn ) { + session = session || new SessionState(); + + if ( session.get( 'enabled' ) ) { + fn( session ); + } + } + + /** + * Decorator to call the inner function at most one time. + * + * @param {Function} fn + * @return {Function} + */ + function atMostOnce( fn ) { + var called = false; + return function () { + if ( !called ) { + fn(); + called = true; + } + }; + } + + // Full text search satisfaction tracking + if ( isSearchResultPage || search.cameFromSearch ) { + $( document ).ready( function () { + setup( setupSearchTest ); + } ); + } + + // Autocomplete satisfaction tracking + $( document ).ready( function () { + if ( autoComplete.cameFromSearch ) { + // user came here by selecting an autocomplete result, + // initialize on page load + setup( setupAutocompleteTest ); + } else { + // delay initialization until the user clicks into the autocomplete + // box. Note there are two elements matching this selector, the + // main search box on Special:Search and the search box on every + // page. $.one fires once per element and not once ever, hence the + // decorator. + $( 'input[type=search]' ).one( 'focus', atMostOnce( function () { + setup( setupAutocompleteTest ); + } ) ); + } + } ); + }( mediaWiki, jQuery ) ); -- To view, visit https://gerrit.wikimedia.org/r/270863 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5438373ed0c53ff524aea4b0548cd850c7e00e92 Gerrit-PatchSet: 12 Gerrit-Project: mediawiki/extensions/WikimediaEvents Gerrit-Branch: master Gerrit-Owner: EBernhardson <ebernhard...@wikimedia.org> Gerrit-Reviewer: Bearloga <mpo...@wikimedia.org> Gerrit-Reviewer: EBernhardson <ebernhard...@wikimedia.org> Gerrit-Reviewer: JGirault <jgira...@wikimedia.org> Gerrit-Reviewer: Jdrewniak <jdrewn...@wikimedia.org> Gerrit-Reviewer: MaxSem <maxsem.w...@gmail.com> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits