Пример #1
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 myresults = await collection.Aggregate()
                            .Group(new BsonDocument("_id", "$groups"))
                            .ToListAsync();

#if NO
            BsonArray array = new BsonArray();
            array.ToArray <string>();
#endif
            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); // 表示结束
        }
Пример #2
0
        // 返回空表示任意匹配
        // parameters:
        //      userCondiction  消息创建者的用户ID的列表,逗号分隔。如果为空,表示不在意消息创建者
        FilterDefinition <MessageItem> BuildQuery(GroupQuery group_query,
                                                  string userCondition,
                                                  string timeRange,
                                                  string idCondition,
                                                  string subjectCondition)
        {
            string strStart = "";
            string strEnd   = "";

            StringUtil.ParseTwoPart(timeRange, "~", out strStart, out strEnd);
            DateTime startTime;
            DateTime endTime;

            try
            {
                startTime = string.IsNullOrEmpty(strStart) ? new DateTime(0) : DateTime.Parse(strStart);
                endTime   = string.IsNullOrEmpty(strEnd) ? new DateTime(0) : DateTime.Parse(strEnd);
            }
            catch (Exception)
            {
                throw new ArgumentException("时间范围字符串 '" + timeRange + "' 不合法", "timeRange");
            }

            FilterDefinition <MessageItem> user_filter = null;

            if (string.IsNullOrEmpty(userCondition) == false)
            {
                string[] list = userCondition.Split(new char[] { ',' });
                List <FilterDefinition <MessageItem> > items = new List <FilterDefinition <MessageItem> >();
                foreach (string user in list)
                {
                    string name = user;
                    if (name.StartsWith("ui:"))
                    {
                        name = name.Substring(3);
                    }
                    FilterDefinition <MessageItem> item = Builders <MessageItem> .Filter.Eq("creator", name);

                    items.Add(item);
                }
                if (items.Count == 1)
                {
                    user_filter = items[0];
                }
                else
                {
                    user_filter = Builders <MessageItem> .Filter.Or(items);
                }
            }

            FilterDefinition <MessageItem> time_filter = null;

            if (startTime == new DateTime(0) && endTime == new DateTime(0))
            {
                time_filter = null;  // Builders<MessageItem>.Filter.Gte("publishTime", startTime);
            }
            else if (startTime == new DateTime(0))
            {
                time_filter = Builders <MessageItem> .Filter.Lt("publishTime", endTime);
            }
            else if (endTime == new DateTime(0))
            {
                time_filter = Builders <MessageItem> .Filter.Gte("publishTime", startTime);
            }
            else
            {
                time_filter = Builders <MessageItem> .Filter.And(
                    Builders <MessageItem> .Filter.Gte("publishTime", startTime),
                    Builders <MessageItem> .Filter.Lt("publishTime", endTime));
            }

            FilterDefinition <MessageItem> expire_filter = Builders <MessageItem> .Filter.Or(
                Builders <MessageItem> .Filter.Eq("expireTime", new DateTime(0)),
                Builders <MessageItem> .Filter.Gt("expireTime", DateTime.Now));

            // 构造一个 AND 运算的检索式
            FilterDefinition <MessageItem> group_filter = group_query.BuildMongoQuery();

            // id 列表
            FilterDefinition <MessageItem> id_filter = null;

            if (string.IsNullOrEmpty(idCondition) == false)
            {
                string[] list = idCondition.Split(new char[] { ',' });
                List <FilterDefinition <MessageItem> > items = new List <FilterDefinition <MessageItem> >();
                foreach (string id in list)
                {
                    FilterDefinition <MessageItem> item = Builders <MessageItem> .Filter.Eq("id", id);

                    items.Add(item);
                }
                if (items.Count == 1)
                {
                    id_filter = items[0];
                }
                else
                {
                    id_filter = Builders <MessageItem> .Filter.Or(items);
                }
            }

            {
                List <FilterDefinition <MessageItem> > items = new List <FilterDefinition <MessageItem> >();
                if (time_filter != null)
                {
                    items.Add(time_filter);
                }
                if (expire_filter != null)
                {
                    items.Add(expire_filter);
                }
                if (group_filter != null)
                {
                    items.Add(group_filter);
                }
                if (user_filter != null)
                {
                    items.Add(user_filter);
                }
                if (id_filter != null)
                {
                    items.Add(id_filter);
                }
                if (string.IsNullOrEmpty(subjectCondition) == false)
                {
                    items.Add(CollectionQuery.BuildMongoQuery(subjectCondition, "subjects"));
                }

                return(Builders <MessageItem> .Filter.And(items));
            }

#if NO
            if (time_filter == null)
            {
                return(Builders <MessageItem> .Filter.And(expire_filter,
                                                          group_filter));
            }

            return(time_filter = Builders <MessageItem> .Filter.And(time_filter,
                                                                    expire_filter,
                                                                    group_filter));
#endif
        }
Пример #3
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();

            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
                    {
                        item.SetPropertyValue(field, temp.ToString());
                    }

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

                index++;
            }

            proc(totalCount, null); // 表示结束
        }
Пример #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))
            {
                while (await cursor.MoveNextAsync())
                {
                    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();
                    item.groups = key.Split(new char[] { ',' });
                    if (proc(totalCount, item) == false)
                    {
                        return;
                    }
                }
                index++;
            }

            proc(totalCount, null); // 表示结束
        }
Пример #5
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
        }
Пример #6
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))
            {
                while (await cursor.MoveNextAsync())
                {
                    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); // 表示结束
            }
        }
Пример #7
0
        public static GroupQuery Build(string strText)
        {
            GroupQuery query = new GroupQuery(strText);

            return(query);
        }