Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The handler parameter from find() is unclear or might need more documentation #236

Open
ColinFay opened this issue Mar 4, 2022 · 2 comments

Comments

@ColinFay
Copy link

ColinFay commented Mar 4, 2022

It's unclear how find(handler = ) works.

The documentation says:

Retrieve fields from records matching query. Default handler will return all data as a single dataframe.

Which seems to imply that defining another handler would allow to return something else than a single dataframe.

Digging into the code, mongo_stream_in does the following:

   cb <- if (is.null(handler)) {
        out <- new.env()
        function(x) {
            if (length(x)) {
                count <<- count + length(x)
                out[[as.character(count)]] <<- x
            }
        }
    }
    else {
        function(x) {
            handler(post_process(x))
            count <<- count + length(x)
        }
    }

meaning that handler() is always called with post_process(), which does:

> mongolite:::post_process
function (x) 
{
    df <- as.data.frame(jsonlite:::simplify(x))
    df
}

So it will always be a dataframe or a list of dataframe?

That raises the following questions:

  • how do I prevent find() from returning a dataframe ?
  • How can I return something else using a handler?

the end of mongo_stream_in is

    if (is.null(handler)) {
        if (verbose) 
            cat("\r Imported", count, "records. Simplifying into dataframe...\n")
        out <- as.list(out, sorted = FALSE)
        post_process(unlist(out[order(as.numeric(names(out)))], 
            FALSE, FALSE))
    }
    else {
        invisible()
    }

so if the handler is defined, nothing is returned?

My use case is the following :

con <- mongolite::mongo()
con$drop()
con$insert(
    list( y = data.frame(x = 1) )
)
# I want this to return list( y = data.frame(x = 1) )
con$find() 
con$insert(
    list( z = data.frame(x = 1) )
)
# I don't want this to return a data.frame
con$find()

To sum up, I don't want the automatic dataframe conversion.
How do we achieve that in find?

@jeroen
Copy link
Owner

jeroen commented Mar 4, 2022

I think find() assumes data frames indeed. If you don't want that, you may want to try iterate(): https://jeroen.github.io/mongolite/query-data.html#iterating

@ColinFay
Copy link
Author

ColinFay commented Mar 4, 2022

Thanks a lot, that definitely matches what I wanted to do :)

I stil feel like the doc is a little bit unclear about what/how handler works, so do you want to keep this issue open?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants