Create paging filters using golang for MongoDB

WBOY
Release: 2024-02-05 21:15:24
forward
637 people have browsed it

使用 golang for MongoDB 创建分页过滤器

Question content

I have a large filter and I will provide a snippet of it. I'm trying to pass a map of the paganization filter but getting the error message

the match filter must be an expression in an object
Copy after login

Get filter

func (app *courses) getfilter(filter *filter) ([]bson.m, error) {
    
        pipeline := make([]bson.m, 0)
    
        if filter.all {
            // include all items
        } else {
            // filter items based on the provided criteria
            if filter.beginner {
                pipeline = append(pipeline, bson.m{"tags": "beginner"})
            }
            if filter.advanced {
                pipeline = append(pipeline, bson.m{"tags": "advanced"})
            }
            if filter.go {
                pipeline = append(pipeline, bson.m{"tags": "go"})
            }
        }
    
        return pipeline, nil
    }
Copy after login

Handler

func (app *courses) coursesallhandler(w http.responsewriter, r *http.request) {
    ctx := context.background()

    clog := log.getloggerfromcontext(ctx)

    p := r.url.query().get("page")
    ps := r.url.query().get("pagesize")

    var filter filter
    err := json.newdecoder(r.body).decode(&filter)
    if err != nil {
        http.error(w, "failed to parse request body", http.statusbadrequest)
        return
    }

    pipeline := make([]bson.m, 0)

    page, _ := strconv.atoi(p)
    pagesize, _ := strconv.atoi(ps)

    // pagination
    skip := (page - 1) * pagesize
    limit := pagesize

    // add filter
    pipeline, err = app.getfilter(&filter)
    if err != nil {
        clog.error(err)
    }
    pipeline = append(pipeline, bson.m{"$match": pipeline})

    // add pagination stages to the pipeline
    pipeline = append(pipeline, bson.m{"$skip": skip})
    pipeline = append(pipeline, bson.m{"$limit": limit})

    res, err := app.repo.getall(ctx, pipeline)
    if err != nil {
        clog.error(err)

        return
    }

    err = app.helper.writejson(w, http.statusok, envelope{"data": res, "metadata": "none"}, nil)
    if err != nil {
        clog.errorctx(err, log.ctx{
            "header":      w.header(),
            "request_url": r.url.string(),
        })
    }

}
Copy after login

How do I get the values ​​set to "true" or "false", put them into a map and submit them in a query to match the database, like I'm trying to do here.

// add filter
pipeline, err = app.getfilter(&filter)
if err != nil {
    clog.error(err)
}
pipeline = append(pipeline, bson.m{"$match": pipeline})
Copy after login

----renew----

I now have:

func (app *courses) coursesallhandler(w http.responsewriter, r *http.request) {
    ctx := context.background()

clog := log.getloggerfromcontext(ctx)

var filter filter
err := json.newdecoder(r.body).decode(&filter)
if err != nil {
    http.error(w, "failed to parse request body", http.statusbadrequest)
    return
}

filter.all = true

pipeline := make([]bson.m, 3)

// add filter
matches, err := app.getfilter(&filter)
if err != nil {
    clog.error(err)
}

pipeline[0] = bson.m{"$skip": 1}
pipeline[1] = bson.m{"$limit": 5}
pipeline[2] = bson.m{"$match": matches}


res, err := app.repo.getall(ctx, pipeline)
if err != nil {
    clog.error(err)

    return
}

err = app.helper.writejson(w, http.statusok, envelope{"data": res, "metadata": "none"}, nil)
if err != nil {
    clog.errorctx(err, log.ctx{
        "header":      w.header(),
        "request_url": r.url.string(),
    })
 }

}
Copy after login

The filter looks like

func (app *courses) getfilter(filter *filter) (bson.m, error) {

    match := bson.m{}
    tags := []string{}

    if filter.all {
        // include all items
        tags = append(tags, "beginner")
        tags = append(tags, "intermediate")
        .....
    } else {
        // filter items based on the provided criteria
        if filter.beginner {
            tags = append(tags, "beginner")
        }
        if filter.advanced {
            tags = append(tags, "advanced")
        }
        if filter.go {
            tags = append(tags, "go")
        }
        ........

    }

    match = bson.m{
        "tags": bson.m{"$in": tags},
    }

    return match, nil
}
Copy after login

Will be used here later..

func (r *CourseRepo) GetAll(ctx context.Context, pipeline []bson.M) ([]Course, error) {
    clog := log.GetLoggerFromContext(ctx)

    cur, err := r.collection.Aggregate(ctx, pipeline)

    ...
Copy after login

But it is empty. Everything in the filter is selected, no errors.


Correct answer


The match filter you get must be an expression in the object because $match requires an object (bson.m), but you have been given a slice object ([]bson.m).

Try this

func (app *Courses) getFilter(filter *Filter) (bson.M, error) {
    match := bson.M{}
    tags := []string{}

    if filter.All {
        // Include all items
    } else {
        // Filter items based on the provided criteria
        if filter.Beginner {
            tags = append(tags, "beginner")
        }
        if filter.Advanced {
            tags = append(tags, "advanced")

        }
        if filter.Go {
            tags = append(tags, "go")
        }

        match = bson.M{
            "tags": bson.M{"$in": tags},
        }
    }

    return match, nil
}
Copy after login

The above is the detailed content of Create paging filters using golang for MongoDB. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template