예제 #1
0
        public async Task <MessageResult> GetMessageAsyncLite(
            GetMessageRequest request,
            Delegate_outputMessage proc,
            TimeSpan timeout,
            CancellationToken token)
        {
            MessageResult result = new MessageResult();

            if (string.IsNullOrEmpty(request.TaskID) == true)
            {
                request.TaskID = Guid.NewGuid().ToString();
            }

            long recieved = 0;

            StringBuilder cache = new StringBuilder();

            using (WaitEvents wait_events = new WaitEvents())    // 表示中途数据到来
            {
                using (var handler = HubProxy.On <
                           string, long, long, IList <MessageRecord>, string, string>(
                           "responseGetMessage",
                           (taskID, resultCount, start, records, errorInfo, errorCode) =>
                {
                    if (taskID != request.TaskID)
                    {
                        return;
                    }

                    if (resultCount == -1 || start == -1)
                    {
                        if (start == -1)
                        {
                            // 表示发送响应过程已经结束。只是起到通知的作用,不携带任何信息
                            // result.Finished = true;
                        }
                        else
                        {
                            result.Value = resultCount;
                            result.ErrorInfo = errorInfo;
                            result.String = errorCode;
                        }
                        wait_events.finish_event.Set();
                        return;
                    }

                    proc(
                        cache,
                        resultCount,
                        start,
                        records,
                        errorInfo,
                        errorCode);

                    if (records != null)
                    {
                        recieved += GetCount(records);      // records.Count;
                    }
                    if (errorCode == "_complete")
                    {
                        result.Value = resultCount;
                        wait_events.finish_event.Set();
                        return;
                    }

                    if (resultCount >= 0 &&
                        IsComplete(request.Start, request.Count, resultCount, recieved) == true)
                    {
                        wait_events.finish_event.Set();
                    }
                    else
                    {
                        wait_events.active_event.Set();
                    }
                }))
                {
                    MessageResult temp = await HubProxy.Invoke <MessageResult>(
                        "RequestGetMessage",
                        request).ConfigureAwait(false);

                    if (temp.Value == -1 || temp.Value == 0 || temp.Value == 2)
                    {
                        return(temp);
                    }

                    // result.String 里面是返回的 taskID

                    await WaitAsync(
                        request.TaskID,
                        wait_events,
                        timeout,
                        token).ConfigureAwait(false);

                    return(result);
                }
            }
        }
예제 #2
0
        // parameters:
        //      field   字段名。例如 groups/subjects
        public async Task GetFieldAggregate(
            string field,
            GroupQuery group_query,
            string userCondition,
            string timeRange,
            string idCondition,
            string subjectCondition,
            int start,
            int count,
            Delegate_outputMessage proc)
        {
            IMongoCollection <MessageItem> collection = this._collection;

            FilterDefinition <MessageItem> filter = BuildQuery(// groupName,
                group_query,
                userCondition,
                timeRange,
                idCondition,
                subjectCondition);

#if NO
            var group = new BsonDocument {
                { "$group",
                  new BsonDocument
                  {
                      { "_id", new BsonDocument
                            {
                                {
                                    "MyUser", "$subject"
                                }
                            } },

                      {
                          "Count", new BsonDocument
                          {
                              {
                                  "$sum", 1
                              }
                          }
                      }
                  } }
            };
#endif

            var myresults = await collection.Aggregate().Match(filter)
//.Group(new BsonDocument("_id", "$subjects"))
                            .Group(
                new BsonDocument
            {
                { "_id", "$" + field },

                {
                    "c", new BsonDocument
                    {
                        {
                            "$sum", 1
                        }
                    }
                }
            }
                )
                            .ToListAsync().ConfigureAwait(false);

            long totalCount = myresults.Count;
            var  index      = 0;
            foreach (BsonDocument doc in myresults)
            {
                if (count != -1 && index - start >= count)
                {
                    break;
                }
                Type type = null;
                if (index >= start)
                {
                    MessageItem item = new MessageItem();

                    // BsonArray array = (doc.GetValue("_id") as BsonArray);
                    if (type == null)
                    {
                        type = item.GetPropertyType(field);
                    }
                    BsonValue temp = doc.GetValue("_id");
                    if (type.Equals(typeof(string[])))
                    {
                        item.SetPropertyValue(field, GetStringArray(temp as BsonArray));
                    }
                    else if (type.Equals(typeof(List <string>))) // 2018/11/14
                    {
                        item.SetPropertyValue(field, new List <string>(GetStringArray(temp as BsonArray)));
                    }
                    else
                    {
                        item.SetPropertyValue(field, temp.ToString());
                    }

                    item.data = doc.GetValue("c").ToString();
                    if (proc(totalCount, item) == false)
                    {
                        return;
                    }
                }

                index++;
            }

            proc(totalCount, null); // 表示结束
        }
예제 #3
0
        // 检索出指定范围的 群名类型
        public async Task GetGroups(
            GroupQuery group_query,
            string timeRange,
            int start,
            int count,
            Delegate_outputMessage proc)
        {
            IMongoCollection <MessageItem> collection = this._collection;

            // List<MessageItem> results = new List<MessageItem>();
            FilterDefinition <MessageItem> filter = BuildQuery(// groupName,
                group_query,
                timeRange);

            var results = await collection
                          .Find(
                filter == null?new BsonDocument() : filter
                )
                          .Project(Builders <MessageItem> .Projection.Include("groups")).ToListAsync();

            List <string> keys  = new List <string>();
            Hashtable     table = new Hashtable(); // groups --> true

            foreach (BsonDocument doc in results)
            {
                string strText = ToString(doc.GetValue("groups") as BsonArray);
                if (strText == null)
                {
                    continue;
                }
                if (table.ContainsKey(strText))
                {
                    continue;
                }
                table[strText] = true;
                keys.Add(strText);
            }

            long totalCount = keys.Count;

            foreach (string key in keys)
            {
                MessageItem item = new MessageItem();
                item.groups = key.Split(new char [] { ',' });
                // var groups = doc.GetValue("_id");

                if (proc(totalCount, item) == false)
                {
                    return;
                }
            }

            proc(totalCount, null); // 表示结束

#if NO
            var myresults = await collection.Aggregate()
                            .Group(new BsonDocument("_id", "$groups"))
                            .ToListAsync();

            long totalCount = myresults.Count;
            foreach (BsonDocument doc in myresults)
            {
                MessageItem item  = new MessageItem();
                BsonArray   array = (doc.GetValue("_id") as BsonArray);
                item.groups = GetStringArray(array);
                // var groups = doc.GetValue("_id");

                if (proc(totalCount, item) == false)
                {
                    return;
                }
            }

            proc(totalCount, null); // 表示结束
#endif
        }
예제 #4
0
        // 这个版本资源耗费厉害
        // 按照条件检索出 MessageItem 中的 group 字段,并归并去重
        // 相当于 Group by 的效果
        public async Task GetGroupsField(
            GroupQuery group_query,
            string timeRange,
            int start,
            int count,
            Delegate_outputMessage proc)
        {
            IMongoCollection <MessageItem> collection = this._collection;

            // List<MessageItem> results = new List<MessageItem>();
            FilterDefinition <MessageItem> filter = BuildQuery(// groupName,
                group_query,
                "",
                timeRange,
                "",
                "");

            // 在遍历过程中,只接收 groups 字段
            // http://stackoverflow.com/questions/32938656/c-sharp-mongo-2-0-reduce-traffic-of-findasync
            var projection = Builders <MessageItem> .Projection
                             .Include(b => b.groups)
                             .Exclude("_id"); // _id is special and needs to be explicitly excluded if not needed

            var options = new FindOptions <MessageItem, MessageItem> {
                Projection = projection
            };

            List <string> keys  = new List <string>();
            Hashtable     table = new Hashtable(); // groups --> true

            using (var cursor = await collection.FindAsync(filter, options).ConfigureAwait(false))
            {
                while (await cursor.MoveNextAsync().ConfigureAwait(false))
                {
                    var batch = cursor.Current;
                    foreach (var document in batch)
                    {
                        if (document.groups == null)
                        {
                            continue;
                        }
                        string strText = string.Join(",", document.groups);
                        if (table.ContainsKey(strText))
                        {
                            continue;
                        }
                        table[strText] = true;
                        keys.Add(strText);
                    }
                }
            }

            long totalCount = keys.Count;
            var  index      = 0;

            foreach (string key in keys)
            {
                if (count != -1 && index - start >= count)
                {
                    break;
                }
                if (index >= start)
                {
                    MessageItem item = new MessageItem();
#if ARRAY
                    item.groups = key.Split(new char[] { ',' });
#else
                    item.groups = new List <string>(key.Split(new char[] { ',' }));
#endif
                    if (proc(totalCount, item) == false)
                    {
                        return;
                    }
                }
                index++;
            }

            proc(totalCount, null); // 表示结束
        }
예제 #5
0
        // parameters:
        //      timeRange   时间范围
        public async Task GetMessages(// string groupName,
            GroupQuery group_query,
            string userCondition,
            string timeRange,
            string sortCondition,
            string idCondition,
            string subjectCondition,
            int start,
            int count,
            Delegate_outputMessage proc)
        {
            IMongoCollection <MessageItem> collection = this._collection;

            // List<MessageItem> results = new List<MessageItem>();
            FilterDefinition <MessageItem> filter = BuildQuery(// groupName,
                group_query,
                userCondition,
                timeRange,
                idCondition,
                subjectCondition);

#if NO
            if (string.IsNullOrEmpty(groupName))
            {
                filter = Builders <MessageItem> .Filter.Or(
                    Builders <MessageItem> .Filter.Eq("group", ""),
                    Builders <MessageItem> .Filter.Eq("group", (string)null));
            }
            else
#endif
            // filter = Builders<MessageItem>.Filter.Eq("group", groupName);

            SortDefinition <MessageItem> sort = null;

            if (string.IsNullOrEmpty(sortCondition))
            {
                sort = Builders <MessageItem> .Sort.Ascending("publishTime");
            }
            else
            {
                List <string> sort_params = StringUtil.ParseTwoPart(sortCondition, "|");
                string        field_name  = sort_params[0];
                // TODO: 需要检查一下 field_name 内容的正确性
                string order_part = sort_params[1];
                if (string.IsNullOrEmpty(order_part) ||
                    order_part == "ascending" ||
                    order_part == "asc")
                {
                    sort = Builders <MessageItem> .Sort.Ascending(field_name);
                }
                else
                {
                    sort = Builders <MessageItem> .Sort.Descending(field_name);
                }
            }

            var options = new FindOptions <MessageItem, MessageItem> {
                Sort = sort
            };

            long totalCount = 0;
            var  index      = 0;
            using (var cursor = await collection.FindAsync(
                       filter == null ? new BsonDocument() : filter
                       , options).ConfigureAwait(false))
            {
                while (await cursor.MoveNextAsync().ConfigureAwait(false))
                {
                    var batch       = cursor.Current;
                    int batch_count = batch.Count <MessageItem>();
                    Console.WriteLine("batch.Count=" + totalCount);
                    foreach (var document in batch)
                    {
                        if (count != -1 && index - start >= count)
                        {
                            break;
                        }
                        if (index >= start)
                        {
                            if (proc(-2, document) == false)    // -2 表示总记录数暂时未知。发送全部结束的时候会单独一次发出总记录数
                            {
                                return;
                            }
                        }
                        index++;
                    }
                    totalCount += batch_count;
                }
                proc(totalCount, null); // 表示结束
            }
        }