【问题标题】:Projecting results from MongoDb Find in F#在 F# 中从 MongoDb Find 投影结果
【发布时间】:2023-04-09 19:15:01
【问题描述】:

我正在尝试使用 MongoDB.Driver 查询 MongoDB 并使用 mongo 投影返回部分结果。

我已经弄清楚如何在没有投影的情况下进行查询,但不是部分结果。 这是我查找结果的函数:

let Find<'a> collectionName (filterDefinition: FilterDefinition<'a>) =
    let collection = database.GetCollection<'a> collectionName
    collection.Find(filterDefinition).ToEnumerable() |> List.ofSeq

这是我如何称呼它的一个例子:

let findByIdFilter id =
    Builders<MyModel>.Filter.Eq((fun s -> s.id), id)

let results = Find collectionName (findByIdFilter id)

假设我的模型是这样的:

type MyInnerModel = {
    zInner: bool
}

type MyModel = {
    id: ObjectId
    x: int
    y: double
    z: MyInnerModel
}

这些是我的预测:

type MyModelProjection1 = {
    id: ObjectId
    y: double
}

type MyModelProjection1 = {
    id: ObjectId
    x: int
    z: MyInnerModel
}

如何针对以下场景构建查询:

  • 查找与(fun (m: MyModel) -&gt; m.z.zInner = false) 匹配并投影到MyModelProjection1 的文档
  • 查找与(fun (m: MyModel) -&gt; m.x = 5) 匹配并投影到MyModelProjection2 的文档
  • 查找投影到MyModelProjection1MyModelProjection2 的所有文档

【问题讨论】:

    标签: .net mongodb f# mongodb-query mongodb.driver


    【解决方案1】:

    您可以像这样定义您的预测:

    let projection1 =
        Builders<MyModel>.Projection.Expression(fun model ->
            { id = model.id; y = model.y })
    
    let projection2 =
        Builders<MyModel>.Projection.Expression(fun model ->
            { id = model.id; x = model.x; z = model.z })
    

    然后您可以通过以下方式使用它们:

        let one =
            collection
                .Find(fun m -> m.z.zInner = false)
                .Project(projection1).ToEnumerable() |> List.ofSeq
    
        let two =
            collection
                .Find(fun m -> m.x = 5)
                .Project(projection2).ToEnumerable() |> List.ofSeq
    
        let three =
            collection
                .Find(fun _ -> true)
                .Project(projection1).ToEnumerable() |> List.ofSeq
    
        let four =
            collection
                .Find(fun _ -> true)
                .Project(projection1).ToEnumerable() |> List.ofSeq
    

    【讨论】:

    • 太棒了!这绝对有效!您是否碰巧知道如何构造一个类似的定义来对结果进行排序? Builders&lt;MyModel&gt;.Sort 似乎没有 .Expression。它有.Ascending(...)(或Descending(...)),需要field: FieldDefinition&lt;SessionSnapshot&gt; -&gt; SortDefinition&lt;SessionSnapshot&gt;,但我不知道如何构造这些......
    • 你可以试试let sortDefintion = Builders&lt;MyModel&gt;.Sort.Descending(fun doc -&gt; doc.x :&gt; obj)
    • 有意义。我希望在不隐藏类型的情况下有更好的方法。谢谢!
    猜你喜欢
    • 2015-05-26
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多