public Result<XDoc> FormatResultSet(SearchResult searchResultSet, SetDiscriminator discriminator, bool explain, TrackingInfo trackingInfo, Result<XDoc> result) { return _instance.FormatResultSet(searchResultSet, discriminator, explain, trackingInfo, result); }
public SearchResult CacheQuery(XDoc searchDoc, SearchQuery query, TrackingInfo trackingInfo) { return _instance.CacheQuery(searchDoc, query, trackingInfo); }
public void FormatResultSet_generates_special_output_for_tracked_searches() { // Arrange var item = new SearchResultItem(1, SearchResultType.Page, "page", 1, DateTime.Parse("2010/10/10").ToSafeUniversalTime()); var detail = new SearchResultDetail(Pairs( "id.page", 1, "path","path", "uri","http://uri", "title", "foo", "author", "bob", "preview", "preview" )); var set = new SearchResult("parsed", new[] { item }); var discriminator = new SetDiscriminator() { Ascending = true, Limit = 100, Offset = 0, SortField = "rank" }; var explain = false; TrackingInfo trackingInfo = new TrackingInfo() { QueryId = 123, PreviousQueryId = 456 }; _cache.Setup(x => x.TryGet(item.DetailKey, out detail)).Returns(true).AtMostOnce().Verifiable(); // Act var xml = Search.FormatResultSet(set, discriminator, explain, trackingInfo, new Result<XDoc>()).Wait(); // Assert _cache.VerifyAll(); var expectedXml = XDocFactory.From(@" <search querycount=""1"" ranking=""adaptive"" queryid=""123"" count=""1""> <parsedQuery>parsed</parsedQuery> <result> <id>1</id> <uri>http://uri</uri> <uri.track>mock://api/site/query/123?pageid=1&rank=1&type=page&position=1</uri.track> <rank>1</rank> <title>foo</title> <page> <title>foo</title> <path>path</path> </page> <author>bob</author> <date.modified>2010-10-10T00:00:00Z</date.modified> <content>preview</content> <type>page</type> </result> </search>", MimeType.TEXT_XML); Assert.AreEqual(expectedXml.ToCompactString(), xml.ToCompactString()); }
public void CacheQuery_can_track_query() { // Arrange InitWithoutAdaptiveSearch(); var searchDoc = XDocFactory.From(@" <documents> <parsedQuery>content:foo</parsedQuery> <document> <id.page>123</id.page> <id.file>1234</id.file> <title>file</title> <date.edited>20100525231800</date.edited> <score>1</score> </document> </documents>", MimeType.TEXT_XML); var trackingInfo = new TrackingInfo() { PreviousQueryId = 123 }; var q = new SearchQuery("raw", "processed", new LuceneClauseBuilder(), null); _cache.Setup(x => x.Set(GetKey(q), It.IsAny<SearchResult>(), It.IsAny<TimeSpan>())).AtMostOnce().Verifiable(); _session.Setup(x => x.SearchAnalytics_LogQuery(q, "content:foo", _user.ID, 1, 123)).Returns(456).AtMostOnce().Verifiable(); // Act Search.CacheQuery(searchDoc, q, trackingInfo); // Assert _session.Verify(x => x.SearchAnalytics_GetPopularityRanking(It.IsAny<string>()), Times.Never()); _session.VerifyAll(); _cache.VerifyAll(); Assert.AreEqual(456, trackingInfo.QueryId); }
private Yield CachedSearch(ISearchBL search, SearchQuery query, SetDiscriminator discriminator, bool explain, TrackingInfo trackingInfo, Result<XDoc> result) { if(query.IsEmpty) { yield return search.FormatResultSet(new SearchResult(), discriminator, false, null, new Result<XDoc>()) .Set(result.Return); yield break; } var searchResultSet = search.GetCachedQuery(query); if(!explain && searchResultSet != null && (trackingInfo == null || trackingInfo.QueryId.HasValue)) { // we can only use the cached result set if we either don't have trackingInfo or the trackInfo has a queryId. Otherwise we have to re-query. yield return search.FormatResultSet(searchResultSet, discriminator, false, trackingInfo, new Result<XDoc>()).Set(result.Return); yield break; } // get search results DreamMessage res = null; var lucene = DekiContext.Current.Deki.LuceneIndex.At("compact").With("wikiid", DekiContext.Current.Instance.Id); yield return lucene.With("q", query.LuceneQuery).GetAsync().Set(x => res = x); if(!res.IsSuccessful) { result.Return(new XDoc("documents").Attr("error", string.Format(DekiResources.ERROR_QUERYING_SEARCH_INDEX, query.Raw.EncodeHtmlEntities()))); yield break; } searchResultSet = search.CacheQuery(FilterResults(res.ToDocument()), query, trackingInfo); yield return search.FormatResultSet(searchResultSet, discriminator, explain, trackingInfo, new Result<XDoc>()) .Set(result.Return); }
public Yield GetRankedSearch(DreamContext context, DreamMessage request, Result<DreamMessage> response) { bool explain = !context.Uri.GetParam("explain", "false").EqualsInvariantIgnoreCase("false"); if(explain) { explain = DetermineAccess(context, request) == DreamAccess.Internal; } string queryString = context.GetParam("q"); // Note (arnec): BUG 7972: want date.created support, which can't happen until lucene indexes it, which can't happen until the // API exposes it, which can't happen until we actuallly can get at it simply for pages (i.e. Resource model) var discriminator = Utils.GetSetDiscriminatorFromRequest(context, 25, "-rank"); var queryId = context.GetParam<ulong>("queryid", 0); var previousQueryId = context.GetParam<ulong>("previousqueryid", 0); string constraint = context.GetParam("constraint", string.Empty); var trackingInfo = new TrackingInfo() { QueryId = queryId == 0 ? null : (ulong?)queryId, PreviousQueryId = previousQueryId == 0 ? null : (ulong?)previousQueryId }; var parser = context.GetParam("parser", SearchQueryParserType.BestGuess); // TODO (arnec): throw on unsupported type // get search results XDoc results = null; var search = Resolve<ISearchBL>(context); var query = search.BuildQuery(queryString, constraint, parser, DekiContext.Current.IsValidApiKeyInRequest); yield return Coroutine.Invoke(CachedSearch, search, query, discriminator, explain, trackingInfo, new Result<XDoc>()) .Set(x => results = x); response.Return(DreamMessage.Ok(results)); yield break; }
private Yield CachedSearch(ISearchBL search, SearchQuery query, SetDiscriminator discriminator, bool explain, TrackingInfo trackingInfo, Result<XDoc> result) { if(query.IsEmpty) { yield return search.FormatResultSet(new SearchResult(), discriminator, false, null, new Result<XDoc>()) .Set(result.Return); yield break; } var searchResultSet = search.GetCachedQuery(query); if(!explain && searchResultSet != null && (trackingInfo == null || trackingInfo.QueryId.HasValue)) { // we can only use the cached result set if we either don't have trackingInfo or the trackInfo has a queryId. Otherwise we have to re-query. yield return search.FormatResultSet(searchResultSet, discriminator, false, trackingInfo, new Result<XDoc>()).Set(result.Return); yield break; } // get search results DreamMessage msg = null; var context = DekiContext.Current; var searchPlug = context.Deki.LuceneIndex .At("compact") .With("q", query.LuceneQuery) .With("wikiid", context.Instance.Id); if(!DekiContext.Current.IsValidApiKeyInRequest) { searchPlug = searchPlug .With("userid", context.User.ID) .With("apiuri", Self.Uri.AsPublicUri().ToString()); } yield return searchPlug .Get(new Result<DreamMessage>()) .Set(x => msg = x); if(!msg.IsSuccessful) { var resources = context.Resources; result.Return(new XDoc("documents").Attr("error", resources.Localize(DekiResources.ERROR_QUERYING_SEARCH_INDEX(query)))); yield break; } searchResultSet = search.CacheQuery(msg.ToDocument(), query, trackingInfo); yield return search.FormatResultSet(searchResultSet, discriminator, explain, trackingInfo, new Result<XDoc>()) .Set(result.Return); }