将过滤器应用于嵌入式文档,过滤出不同的值

时间:2019-02-08 14:34:31

标签: c# mongodb filter distinct

因此,我在文档和子文档上构建了一个过滤器,然后将该过滤器传递到一个不同的查询中。我想在光标中使用该查询,但出现错误,无法从用法中推断出FindAsync。尝试显式指定类型参数。

我是Mongodb的新手,任何帮助都很棒。如果我只是通过过滤器,则此方法有效,但是我只需要不同的文档。

       var builder = Builders<newMsg>.Filter;
       var filter = builder.Eq("type", "CREATE") & builder.Eq("entities.errorCondition", 14);
    // var result = collection.Find(filter).ToList();
        IList<newMsg> distinct = collection.Distinct<newMsg>("entities.ID", filter).ToList<newMsg>();

        if (distinct.Count > 0)
        {
            using (IAsyncCursor<newMsg> cursor = await collection.FindAsync(distinct))
            {
                while (await cursor.MoveNextAsync())
                {
                    IEnumerable<newMsg> batch = cursor.Current;
                    foreach (newMsg document in batch)
                    {
                        //This gives me the entire list as a string
                        var subDocument = document.Entities;
                        foreach (var sd in subDocument)
                        {
                          //do some stuff

                        }
                    }
                }
            }
        }
    }

我的班级文件看起来像这样

    [BsonIgnoreExtraElements]
    internal class newMsg
    {
        [BsonId]
        public ObjectId _id { get; set; }

        [BsonElement("type")]
        public string Type { get; set; }

        [BsonElement("entities")]
        public List<entity> Entities { get; set; }
    }
    [BsonIgnoreExtraElements]
    internal class entity : newMsg
    {
        [BsonElement("errorCondition")]
        public double ErrorCondition { get; set; }

        [BsonElement("ID")]
        public string ID { get; set; }
    }

1 个答案:

答案 0 :(得分:0)

我最终创建了2个循环,一个循环用于重复,另一个循环用于不同的值,虽然效果不佳,但是可以正常工作。

        var builder = Builders<newMsg>.Filter;
        var filter = builder.Eq("Type", "CREATE") & builder.Eq("Entities.ErrorCondition", 14) & builder.Eq("MsgRead", false);

        var result = collection.Find(filter).ToList();

        if (result.Count > 0)
        {
            //Create a list of distinct msgs, then set msgRead to True, then pass that list to a new filter  
            var distinctMsg = collection.Distinct(new StringFieldDefinition<newMsg, string>("Entities.ID"), FilterDefinition<newMsg>.Empty).ToList();
            foreach (var dm in distinctMsg)
            {
                var entityID = dm;
                var msgUnread = Builders<newMsg>.Filter.Eq("msgRead", false);
                var msgUpdate = Builders<newMsg>.Update.Set("msgRead", true);
                var msgIsRead = collection.UpdateOne(msgUnread, msgUpdate);

                //Create another filter on the distinct messages
                CreateDistinctFilter(mongoClient, db, collection, entityID, ec);
            }

            using (IAsyncCursor<newMsg> cursor = await collection.FindAsync(filter))
            {
                while (await cursor.MoveNextAsync())
                {
                    IEnumerable<newMsg> batch = cursor.Current;
                    foreach (newMsg document in batch)
                    {
                        //This gives me the entire list as a string
                        var subDocument = document.Entities;
                        foreach (var sd in subDocument)
                        {
                         //log duplicate msg
                        }
                    }
                }
            }
        }

   static async void CreateDistinctFilter(MongoClient mongoClient, IMongoDatabase db, IMongoCollection<newMsg> collection, string entityID, string ec)
    {
        var builder = Builders<newMsg>.Filter;
        var distinctFilter = builder.Eq("Entities.ID", entityID) & builder.Eq("MsgRead", true);
        var result = collection.Find(distinctFilter).ToList();

        using (IAsyncCursor<newMsg> cursor = await collection.FindAsync(distinctFilter))
        {
            while (await cursor.MoveNextAsync())
            {
                IEnumerable<newMsg> batch = cursor.Current;
                foreach (newMsg document in batch)
                {
                    //This gives me the entire list as a string
                    var subDocument = document.Entities;
                    foreach (var sd in subDocument)
                    {
                        string DeviceName = sd.Name;
                        string Title = DeviceName + " Device DOWN";
                        string Msg = sd.Reason + sd.ID;
                        string ErrorCondition = ec;

                        Console.WriteLine("UNIQUE: " + " " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff") + Msg );
                        Console.WriteLine();


                        }
                    }
                }
            }
        }
    }