. net使用MongoDB根据子文档列表进行选择

本文关键字:列表 行选 选择 文档 使用 MongoDB net | 更新日期: 2023-09-27 18:13:00

我有一个客户数据库,其中包含客户ip地址范围的列表,以便他们访问系统。

public class Customer
{
    [BsonId]
    public ObjectId Id { get; set; }
    public string Name { get; set; }
    public List<IPRange> IPRanges { get; set; }
}
public class IPRange
{
    public int Lower { get; set; }
    public int Upper { get; set; }
}

ip被转换为整数,因此更容易(或至少我认为是)将它们与传入ip地址进行比较。

MongoDB中的文档是这样的

{
    "_id": ObjectID("55f9ab5ac95fb323d8b724a8"),
    "Name": "Customername",
    "IPRanges": [
        {
            "Lower": 134743044,
            "Upper": 134744072
        }, 
        {
            "Lower": 3494108380,
            "Upper": 3494108894
        }
    ],
}

那么问题是,如何根据IP数组比较传入IP和客户IP ?如果不可能,如何以更好的方式做到这一点?

我已经尝试了很多组合,没有一个是有效的。我已经设法得到它的工作,如果上和下的ip是相同的。

这是我得到的最接近的解

    private async static Task<bool> check(string ip = "")
    {
        db = Connect();
        var intIp = IPCalculator.IPToInt(ip); //converts the ip from string form e.g. "8.8.8.8" to integer
        var lowerFilter = Builders<IPRange>.Filter.Gte("Lower", intIp);
        var upperFilter = Builders<IPRange>.Filter.Lte("Upper", intIp);
        List<FilterDefinition<IPRange>> filters = new List<FilterDefinition<IPRange>>();
        filters.Add(lowerFilter);
        filters.Add(upperFilter);
        var customerFilter = Builders<Customer>.Filter.ElemMatch<IPRange>(ca => ca.IPRanges, Builders<IPRange>.Filter.And(filters));

        var customerCollection = db.GetCollection<Customer>("Customer").Find(customerFilter);
        var customerList = await customerCollection.ToListAsync();
        if (customerList.Count > 0)
        {
            return true;
        }
        return false;
    }

. net使用MongoDB根据子文档列表进行选择

看来你搞砸了一点:

var lowerFilter = Builders<IPRange>.Filter.Gte("Lower", intIp);
var upperFilter = Builders<IPRange>.Filter.Lte("Upper", intIp);

因为这意味着Lower>= ip和Upper <= ip。你需要:

var lowerFilter = Builders<IPRange>.Filter.Lte("Lower", intIp);
var upperFilter = Builders<IPRange>.Filter.Gte("Upper", intIp);