查询mongo文档数组

时间:2018-08-23 08:30:27

标签: c# mongodb mongodb-query

我有下一个mongo文档结构:
_id
-countryCode
-keywordID
名称
-displayName
-categories:[Array]
-_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 个答案:

答案 0 :(得分:1)

您的In函数在普通的mongoDB中看起来像一个“ categories._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();
    }
}