Ejemplo n.º 1
0
        public void GetRenderedConcordance(ref string query, int ofs, out string html,
                                           string lang, bool isMobile, HttpContext ctxt)
        {
            StringBuilder sb = new StringBuilder();

            html = "";
            int limit = pageSize;

            query = query.Trim();
            string queryToLog = query;

            if (query.Length == 0)
            {
                return;
            }
            bool isZhoSearch = hasHanzi(query);

            if (!isZhoSearch)
            {
                query = pruneSurf(query, true, null);
            }

            // Lookup timer
            Stopwatch swatch = new Stopwatch();

            swatch.Restart();
            // Lookup
            SphinxResult sres = sphinx.Query(query, isZhoSearch, ofs, limit);

            // If first page, show result count on top
            if (ofs == 0 && sres.TotalCount > 0)
            {
                sb.Append("<p class='corpresultcount'><span>");
                sb.Append(HtmlEncoder.Default.Encode(getResultCountStr(lang, sres.TotalCount)));
                sb.AppendLine("</span></p>");
            }

            using (BinReader br = new BinReader(sphinx.CorpusBinFileName))
            {
                List <float>  trgHilites  = new List <float>();
                List <float>  srcHilites  = new List <float>();
                HashSet <int> usedPoss    = new HashSet <int>();
                int           resultCount = 0;
                // Render surface search results
                foreach (int pos in sres.SurfSegPositions)
                {
                    ++resultCount;
                    usedPoss.Add(pos);
                    br.Position = pos;
                    CorpusSegment cseg = new CorpusSegment(br);
                    if (isZhoSearch)
                    {
                        buildHilitesZhoToHu(query, cseg, trgHilites, srcHilites);
                    }
                    else
                    {
                        buildHilitesHuToZho(query, null, cseg, trgHilites, srcHilites);
                    }
                    sb.Append("<div class='corprow'><div class='corpseg zho'>");
                    sb.Append(renderSegment(cseg.ZhSurf, srcHilites, isZhoSearch));
                    sb.Append("</div><div class='corpseg trg'>");
                    sb.Append(renderSegment(cseg.TrgSurf, trgHilites, isZhoSearch));
                    sb.AppendLine("</div></div>");
                }
                // Render stem search results to fill up to limit
                for (int i = 0; i < sres.StemmedSegs.Count && resultCount < limit; ++i)
                {
                    int pos = sres.StemmedSegs[i].Key;
                    if (usedPoss.Contains(pos))
                    {
                        continue;
                    }
                    ++resultCount;
                    br.Position = pos;
                    CorpusSegment cseg = new CorpusSegment(br);
                    buildHilitesHuToZho(sres.StemmedQuery, sres.StemmedSegs[i].Value, cseg, trgHilites, srcHilites);
                    sb.Append("<div class='corprow'><div class='corpseg zho'>");
                    sb.Append(renderSegment(cseg.ZhSurf, srcHilites, isZhoSearch));
                    sb.Append("</div><div class='corpseg trg'>");
                    sb.Append(renderSegment(cseg.TrgSurf, trgHilites, isZhoSearch));
                    sb.AppendLine("</div></div>");
                }
            }
            // "Load more" button
            if (sres.TotalCount > ofs + limit)
            {
                string strMore = TextProvider.Instance.GetString(lang, "search.corpusLoadMore");
                sb.Append("<div class='corpmore'>");
                sb.Append("<div class='corpmorebtn' data-offset='" + (ofs + limit).ToString() + "' ");
                sb.Append("data-query='" + HtmlEncoder.Default.Encode(query) + "'>");
                sb.Append(HtmlEncoder.Default.Encode(strMore));
                sb.Append("<i class='fa fa-circle-o-notch fa-fw'></i>");
                sb.AppendLine("</div></div>");
            }
            // The response!
            html = sb.ToString();

            // Query log
            int    msecFull      = (int)swatch.ElapsedMilliseconds;
            int    msecPerlOuter = (int)(1000.0F * sres.PerlOuterElapsed);
            string country;
            string xfwd = ctxt.Request.Headers["X-Real-IP"];

            if (xfwd != null)
            {
                country = cres.GetContryCode(IPAddress.Parse(xfwd));
            }
            else
            {
                country = cres.GetContryCode(ctxt.Connection.RemoteIpAddress);
            }
            qlog.LogCorpus(country, isMobile, lang, sres.TotalCount,
                           msecPerlOuter, msecFull, isZhoSearch, ofs > 0, query);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 执行查询
        /// </summary>
        /// <returns></returns>
        public IList<SphinxResult> RunQueries()
        {
            var reqsCount = this._reqs.Count();
            var reqsLength = this._reqs.Sum(r => r.Length);
            var req = new SphReq();
            req.Write(1);
            req.Write((short)SearchCommand.SEARCHD_COMMAND_SEARCH);
            req.Write((short)Command.VER_COMMAND_SEARCH);
            req.Write((int)(4 + reqsLength));
            req.Write(reqsCount);
            foreach (var r in this._reqs) req.Mosaic(r.CutOffHead());
            var conn = this.GetConnection();
            conn.Send(req.GetBuffer());

            var receive = new byte[1024 * 512];
            var receLen = conn.Receive(receive);
            conn.Dispose();

            var rep = new SphRep(receive, receLen);
            var len = this.CheckResponse(rep);
            var sphinxResultList = new List<SphinxResult>();
            for (int rc = 0; rc < reqsCount; rc++)
            {
                var sphinxResult = new SphinxResult()
                {
                    AttrName = new List<string>(),
                    AttrTypes = new List<int>(),
                    Fields = new List<string>(),
                    Matches = new List<SphinxMatch>(),
                    Words = new List<SphinxWordInfo>(),
                    Status = rep.ReadInt()
                };
                if (sphinxResult.Status != (int)SearchStatus.SEARCHD_OK)
                {
                    if (sphinxResult.Status == (int)SearchStatus.SEARCHD_WARNING)
                    {
                        sphinxResult.WarnStr = Encoding.UTF8.GetString(rep.Read(len - 4));
                    }
                    else
                    {
                        sphinxResult.ErrStr = Encoding.UTF8.GetString(rep.Read(len - 4));
                        return null;
                    }
                }
                var fieldsNum = rep.ReadInt();
                for (int i = 0; i < fieldsNum; i++) sphinxResult.Fields.Add(rep.ReadStringNode());
                var attrNum = rep.ReadInt();
                for (int i = 0; i < attrNum; i++)
                {
                    sphinxResult.AttrName.Add(rep.ReadStringNode());
                    sphinxResult.AttrTypes.Add(rep.ReadInt());
                }
                var matchNum = rep.ReadInt();
                var id64 = rep.ReadInt();
                long doc;
                for (int i = 0; i < matchNum; i++)
                {
                    doc = 0 == id64 ? rep.ReadInt() : rep.ReadLong();
                    var docInfo = new SphinxMatch()
                    {
                        DocID = doc,
                        Weight = rep.ReadInt(),
                        AttrValues = new List<object>()
                    };
                    foreach (var type in sphinxResult.AttrTypes)
                    {
                        switch ((AttributeType)System.Enum.Parse(typeof(AttributeType), type.ToString()))
                        {
                            case AttributeType.SPH_ATTR_BIGINT:
                                docInfo.AttrValues.Add(rep.ReadLong());
                                rep.Read(8);
                                break;

                            case AttributeType.SPH_ATTR_FLOAT:
                                docInfo.AttrValues.Add(rep.ReadSingle());
                                rep.Read(8);
                                break;

                            case AttributeType.SPH_ATTR_MULTI:
                                var itemsNum = rep.ReadLong();
                                var vars = new List<long>();
                                for (int j = 0; j < itemsNum; j++) vars.Add(rep.ReadLong());
                                docInfo.AttrValues.Add(vars);
                                break;

                            default:
                                rep.Read(8);
                                docInfo.AttrValues.Add(rep.ReadLong());
                                break;
                        }
                    }
                    sphinxResult.Matches.Add(docInfo);
                }
                sphinxResult.Total = rep.ReadInt();
                sphinxResult.TotalFound = rep.ReadInt();
                sphinxResult.Time = rep.ReadInt();
                var wordNum = rep.ReadInt();
                for (int i = 0; i < wordNum; i++) sphinxResult.Words.Add(new SphinxWordInfo()
                {
                    Word = rep.ReadStringNode(),
                    Docs = rep.ReadInt(),
                    Hits = rep.ReadInt()
                });
                sphinxResultList.Add(sphinxResult);
            }
            return sphinxResultList;
        }
Ejemplo n.º 3
0
        public IActionResult Go([FromQuery] string query)
        {
            int          limit = 100;
            SearchResult res   = new SearchResult();

            query           = query.Trim();
            res.ActualQuery = query;
            if (query.Length == 0)
            {
                return(new ObjectResult(res));
            }

            bool isZhoSearch = hasHanzi(query);

            if (!isZhoSearch)
            {
                query = pruneSurf(query, true, null);
            }
            res.ActualQuery = query;

            SphinxResult sres = Sphinx.Query(query, isZhoSearch, limit);

            if (sres == null)
            {
                return(StatusCode(500));
            }
            using (BinReader br = new BinReader("zhhu-data.bin"))
            {
                List <float>  trgHilites  = new List <float>();
                List <float>  srcHilites  = new List <float>();
                HashSet <int> usedPoss    = new HashSet <int>();
                int           resultCount = 0;
                // Render surface search results
                foreach (int pos in sres.SurfSegPositions)
                {
                    ++resultCount;
                    usedPoss.Add(pos);
                    br.Position = pos;
                    CorpusSegment cseg = new CorpusSegment(br);
                    if (isZhoSearch)
                    {
                        buildHilitesZhoToHu(query, cseg, trgHilites, srcHilites);
                    }
                    else
                    {
                        buildHilitesHuToZho(query, null, cseg, trgHilites, srcHilites);
                    }
                    res.SrcSegs.Add(renderSegment(cseg.ZhSurf, srcHilites, isZhoSearch));
                    res.TrgSegs.Add(renderSegment(cseg.TrgSurf, trgHilites, isZhoSearch));
                }
                // Render stem search results to fill up to limit
                for (int i = 0; i < sres.StemmedSegs.Count && resultCount < limit; ++i)
                {
                    int pos = sres.StemmedSegs[i].Key;
                    if (usedPoss.Contains(pos))
                    {
                        continue;
                    }
                    ++resultCount;
                    br.Position = pos;
                    CorpusSegment cseg = new CorpusSegment(br);
                    buildHilitesHuToZho(sres.StemmedQuery, sres.StemmedSegs[i].Value, cseg, trgHilites, srcHilites);
                    res.SrcSegs.Add(renderSegment(cseg.ZhSurf, srcHilites, isZhoSearch));
                    res.TrgSegs.Add(renderSegment(cseg.TrgSurf, trgHilites, isZhoSearch));
                }
            }
            return(new ObjectResult(res));
        }