Ejemplo n.º 1
0
 public Result<XDoc> FormatResultSet(SearchResult searchResultSet, SetDiscriminator discriminator, bool explain, TrackingInfo trackingInfo, Result<XDoc> result) {
     return _instance.FormatResultSet(searchResultSet, discriminator, explain, trackingInfo, result);
 }
Ejemplo n.º 2
0
 public SearchResult CacheQuery(XDoc searchDoc, SearchQuery query, TrackingInfo trackingInfo) {
     return _instance.CacheQuery(searchDoc, query, trackingInfo);
 }
Ejemplo n.º 3
0
        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&amp;rank=1&amp;type=page&amp;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());
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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;
        }
Ejemplo n.º 7
0
        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);
        }