代码之家  ›  专栏  ›  技术社区  ›  Coder

查询mongo文档数组

  •  0
  • Coder  · 技术社区  · 6 年前

    我有下一个mongo文档结构:

    -国家代码
    -关键字ID
    -姓名
    -显示名称
    -类别:[数组]

    -姓名
    -职位

    我想只知道类别的ID就得到特定类别中的所有关键字。我正在使用mongo C驱动程序,但不知道如何检查数组中的内容。
    我想发送一个带有类别ID的列表,并从该列表中获取具有类别的所有关键字。

    public async Task<List<Keyword>> GetKeywords(List<long> keywordCatIds, string countryCode)
    {
        var mongoCollection = MongoDatabase.GetCollection<Keyword>("Keywords");
        try
        {
            FilterDefinition<Keyword> mongoFilter = Builders<Keyword>.Filter.In(c=>c.Categories, keywordCatIds);
            return await mongoCollection.Find(mongoFilter,null).ToListAsync<Keyword>();
        }
        catch (Exception ex)
        {
            Logger.Error(ex, "Multiple ids for Country Code: {0}, ids: {1}", countryCode, string.Join(',', keywordCatIds.Select(s => s)));
            return null;
        }
    
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   ntohl    5 年前

    你的 In 函数看起来像普通mongoDB中的“categories.\u id”过滤器。转变成 ElemMatch . 我创建了一个填充数据库的项目,然后选择

    特定类别中的所有关键字只知道该类别的ID

    public class CustomID
    {
        public string CountryCode { get; set; }
        public long KeywordId { get; set; }
        public string Name { get; set; }
    }
    
    public class Keyword
    {
        [BsonId]
        public CustomID Id { get; set; }
        public List<Category> Categories { get; set; }
    }
    
    public class Category
    {
        [BsonId]
        public long Id { get; set; }
        public string Name { get; set; }
        public int Position { get; set; }
    }
    
    internal class Program
    {
        public static IMongoDatabase MongoDatabase { get; private set; }
    
        public static async Task Main()
        {
            var conventionPack = new ConventionPack
            {
                new CamelCaseElementNameConvention()
            };
    
            ConventionRegistry.Register(
                "CustomConventionPack",
                conventionPack,
                t => true);
            var client = new MongoClient();
            MongoDatabase = client.GetDatabase("SO");
            var ret = await GetKeywords(new List<long> {1L, 2L}, "HU-hu");
            // ret is A and B. C is filtered out because no category id of 1L or 2L, D is not HU-hu
        }
    
        public static async Task<List<Keyword>> GetKeywords(List<long> keywordCatIds, string countryCode)
        {
            var mongoCollection = MongoDatabase.GetCollection<Keyword>("keywords");
            // be ware! removes all elements. For debug purposes uncomment>
            //await mongoCollection.DeleteManyAsync(FilterDefinition<Keyword>.Empty);
            await mongoCollection.InsertManyAsync(new[]
            {
                new Keyword
                {
                    Categories = new List<Category>
                    {
                        new Category {Id = 1L, Name = "CatA", Position = 1},
                        new Category {Id = 3L, Name = "CatC", Position = 3}
                    },
                    Id = new CustomID
                    {
                        CountryCode = "HU-hu",
                        KeywordId = 1,
                        Name = "A"
                    }
                },
                new Keyword
                {
                    Categories = new List<Category>
                    {
                        new Category {Id = 2L, Name = "CatB", Position = 2}
                    },
                    Id = new CustomID
                    {
                        CountryCode = "HU-hu",
                        KeywordId = 2,
                        Name = "B"
                    }
                },
                new Keyword
                {
                    Categories = new List<Category>
                    {
                        new Category {Id = 3L, Name = "CatB", Position = 2}
                    },
                    Id = new CustomID
                    {
                        CountryCode = "HU-hu",
                        KeywordId = 3,
                        Name = "C"
                    }
                },
                new Keyword
                {
                    Categories = new List<Category>
                    {
                        new Category {Id = 1L, Name = "CatA", Position = 1}
                    },
                    Id = new CustomID
                    {
                        CountryCode = "EN-en",
                        KeywordId = 1,
                        Name = "EN-A"
                    }
                }
            });
            var keywordFilter = Builders<Keyword>.Filter;
            var categoryFilter = Builders<Category>.Filter;
            var mongoFilter =
                keywordFilter.ElemMatch(k => k.Categories, categoryFilter.In(c => c.Id, keywordCatIds)) &
                keywordFilter.Eq(k => k.Id.CountryCode, countryCode);
            return await mongoCollection.Find(mongoFilter).ToListAsync();
        }
    }