Example #1
0
 /// <summary>
 /// 获取连接
 /// </summary>
 /// <returns></returns>
 private Socket GetConnection()
 {
     var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
     var ipEndPoint = new IPEndPoint(IPAddress.Parse(this.Host), this.Port);
     socket.ReceiveTimeout = this.TimeOut;
     try
     {
         socket.Connect(ipEndPoint);
     }
     catch
     {
         throw;
     }
     var rep = new byte[4];
     var len = socket.Receive(rep);
     var sphrep = new SphRep(rep, len);
     var version = sphrep.ReadInt();
     if (version < 1) throw new Exception(string.Format("expected searchd protocol version 1+, got version {0}", version));
     return socket;
 }
Example #2
0
 /// <summary>
 /// 检查返回数据
 /// </summary>
 /// <param name="rep"></param>
 /// <returns>长度</returns>
 private int CheckResponse(SphRep rep)
 {
     var status = rep.ReadShort();
     var ver = rep.ReadShort();
     var len = rep.ReadInt();
     switch (status)
     {
         case (short)SearchStatus.SEARCHD_OK:
         case (short)SearchStatus.SEARCHD_WARNING: break;
         case (short)SearchStatus.SEARCHD_ERROR:
             var response = rep.Read(len);
             throw new Exception("Search Error:" + Encoding.UTF8.GetString(response));
         case (short)SearchStatus.SEARCHD_RETRY:
             var response2 = rep.Read(len);
             throw new Exception("Temporary Search Error:" + Encoding.UTF8.GetString(response2));
         default:
             throw new Exception(string.Format("Unknow Status Code:{0}", status));
     }
     return len;
 }
Example #3
0
 /// <summary>
 /// 构建分词
 /// </summary>
 /// <param name="query">带分词的语句</param>
 /// <param name="index">引用的索引库</param>
 /// <returns>分词集合</returns>
 public IList<SphinxKeyWord> BuildKeywords(string query, string index)
 {
     Contract.Requires(false == string.IsNullOrWhiteSpace(query), "query can not be null or emtpy");
     Contract.Requires(false == string.IsNullOrWhiteSpace(index), "index can not be null or empty");
     var req = new SphReq();
     req.Write(query);
     req.Write(index);
     req.Write(1);
     var tmp = new SphReq();
     tmp.Write(1);
     tmp.Write((short)SearchCommand.SEARCHD_COMMAND_KEYWORDS);
     tmp.Write((short)Command.VER_COMMAND_KEYWORDS);
     tmp.Write((int)req.Length);
     req.Mosaic(tmp.CutOffHead(), SphReq.BlockMosaicLocation.Top);
     var conn = this.GetConnection();
     conn.Send(req.GetBuffer());
     var rece = new byte[5 * req.Length];
     var receLength = conn.Receive(rece);
     var rep = new SphRep(rece, receLength);
     var rLen = this.CheckResponse(rep);
     var nwords = rep.ReadInt();
     var res = new List<SphinxKeyWord>();
     for (int i = 0; i < nwords; i++) res.Add(new SphinxKeyWord(rep.ReadStringNode(), rep.ReadStringNode(), rep.ReadInt(), rep.ReadInt()));
     return res;
 }
Example #4
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;
        }
Example #5
0
        /// <summary>
        /// 构建摘录
        /// </summary>
        /// <param name="docs">待构建的字符串集合</param>
        /// <param name="index">引用的索引库</param>
        /// <param name="words">关键字字串</param>
        /// <param name="options">构建选型</param>
        /// <returns>构建完成的摘录集合</returns>
        public IList<string> BuildExcerpts(IList<string> docs, string index, string words, SphinxBuildExceptsOptions options)
        {
            Contract.Requires(false == string.IsNullOrWhiteSpace(index), "index can not be null");
            Contract.Requires(false == string.IsNullOrWhiteSpace(words), "words can not be null");
            var flag = 1;
            if (options.ExactPhrase) flag |= 2;
            if (options.SinglePassage) flag |= 4;
            if (options.UseBoundaries) flag |= 8;
            if (options.WeightOrder) flag |= 16;

            var req = new SphReq();
            req.Write(0);
            req.Write(flag);
            req.Write(index);
            req.Write(words);
            req.Write(options.BeforeMatch);
            req.Write(options.AfterMatch);
            req.Write(options.ChunkSeparator);
            req.Write(options.Limit);
            req.Write(options.Around);
            req.Write(docs.Count());
            foreach (var doc in docs) req.Write(doc);
            var tmp = new SphReq();
            tmp.Write(1);
            tmp.Write((short)SearchCommand.SEARCHD_COMMAND_EXCERPT);
            tmp.Write((short)Command.VER_COMMAND_EXCERPT);
            var reqLength = (int)req.Length;
            tmp.Write(reqLength);
            req.Mosaic(tmp.CutOffHead(), SphReq.BlockMosaicLocation.Top);
            var conn = this.GetConnection();
            conn.Send(req.GetBuffer());

            var rece = new byte[(int)(1.5 * reqLength)];
            var receLength = conn.Receive(rece);
            conn.Close();
            var rep = new SphRep(rece, receLength);
            var repLength = this.CheckResponse(rep);
            var res = new List<string>();
            for (int i = 0; i < docs.Count(); i++) res.Add(rep.ReadStringNode());
            return res;
        }