{"slug": "mongo-predict-create-your-own-jev", "title": "mongo-predict: create your own Jev", "summary": "Voyage AI released mongo-predict, a Python package (pymongopredict) that fits a model on MongoDB documents where a field is populated and predicts that field for documents where it is missing, invoked through a $predict aggregation stage. The package defaults to XGBoost or any scikit-learn estimator over embeddings from a pre-trained embedding model, stores fitted models in a __mongopredict_models collection, and is offered as both open source and an API; Voyage AI claims it is \"far more accurate than competitors like Jev.\" The examples use MongoDB's sample_mflix.movies collection, training on films with year below 2010 and predicting imdb.rating for later movies.", "body_md": "**mongo-predict** (Python package `pymongopredict`) learns from the documents you already have and fills in a field for\nthe documents that lack it, such as a movie's rating or a new order's fraud flag. You fit a model once to your data,\nthen ask for predictions in an aggregation pipeline. By making use of your data (and a pre-trained embedding model), this gives you predictions that are **far more accurate than competitors like Jev**. We release both an open-source and an API option.\n\n**Contents:** [1. What it does](#1-what-it-does) · [2. Quick start](#2-quick-start) ·\n[3. How it works](#3-how-it-works) · [4. Results](#4-results) · [5. Recipes](#5-recipes) ·\n[6. Good to know](#6-good-to-know) · [7. For data scientists: the embeddings API](#7-for-data-scientists-the-embeddings-api) ·\n[Documentation, demos and development](#documentation-demos-and-development)\n\nIn many collections a field is set in some documents and missing in others. A new movie has no rating yet, and an\noutcome is only known later. mongo-predict learns from the documents that have the field and predicts it for the\ndocuments that do not (Fig. [1](#fig-1)). The examples use MongoDB's `sample_mflix.movies` collection, which is part of the\nsample data you can load into any Atlas cluster.\n\n**Figure 1.** Movies with a known rating (blue) teach the model; `$predict` adds a predicted rating (orange) to newer\nmovies. These are real ratings and predictions; the actual ratings of the newer movies are in Table [1](#tab-1).\n\nThe model reads every field you give it as text, so the plot, the list of genres, the cast and the directors count\nas well as the year or the runtime (Sec. [4](#4-results)).\n\nInstall the package from GitHub and connect to your database as usual:\n\n```\npip install \"pymongopredict @ git+https://github.com/voyage-ai/mongo-predict\"\npython\nfrom pymongo import MongoClient\nfrom pymongopredict import PredictionModel, predictions_api\n\npredictions_api.enable()   # lets coll.aggregate() understand $predict\nmovies = MongoClient(\"mongodb://localhost:27017\").sample_mflix.movies\n\n# 1. Fit a model once, to movies whose rating is known\nmovies.create_prediction_model(PredictionModel(\n    {\n        \"target\": \"imdb.rating\",                                       # the field to predict\n        \"embedFields\": [\"title\", \"year\", \"runtime\", \"rated\",           # the fields to read\n                        \"genres\", \"cast\", \"directors\", \"plot\"],\n        \"filter\": {\"year\": {\"$lt\": 2010}},                             # learn from older movies\n    },\n    name=\"imdb_rating\",\n))\n\n# 2. Use it in any aggregation pipeline\nmovies.aggregate([\n    {\"$predict\": {\"model\": \"imdb_rating\", \"filter\": {\"year\": {\"$gte\": 2010}}}},\n    {\"$sort\": {\"p\": {\"$meta\": \"prediction\"}}},       # best predicted first\n    {\"$limit\": 10},\n    {\"$project\": {\"title\": 1, \"predicted_rating\": {\"$meta\": \"prediction\"}}},\n])\n```\n\nFitting reads the movies, fits the model and stores it in your database (in a collection named\n`__mongopredict_models`), together with how accurate it was on movies it did not see while fitting\n(`movies.list_prediction_models()`). After that, any pipeline can start with `$predict`. The\n[predictions API documentation](https://github.com/mishelsikder/mongo-predict/blob/main/docs/pymongopredict/predictions_api.html) lists every setting of a model\n(`PredictionModel`, `create_prediction_model`) and of the stage (` aggregate`).\n\nFig. [2](#fig-2) follows one movie through the model. A model cannot read a document directly, so the movie is first turned\ninto an **embedding**: a list of numbers produced by an embedding model, built so that documents with similar\nmeaning get similar numbers (two crime dramas end up closer to each other than to a children's cartoon). A\nprediction model (XGBoost by default, or any scikit-learn estimator), learned once from the movies whose rating is\nknown, then turns these numbers into a rating.\n\nThe embedding model is chosen with `\"embeddingModel\"` in the model definition, and it can run in one of two places:\n\n- **On your own machine.** The default,`\"voyage-4-nano\"` , is a small Voyage model that is downloaded once and runs\nlocally, on a GPU if there is one. Any embedding model on Hugging Face works the same way, by its name (for example`\"sentence-transformers/all-MiniLM-L6-v2\"` ). Your documents do not leave your machine.\n- **Through the Voyage API.** Larger Voyage models (`\"voyage-4\"` ,`\"voyage-4-large\"` and soon`\"voyage-json\"` ) run on\nVoyage's servers and need no GPU. Set`VOYAGE_API_KEY` to a key from the[Voyage\ndashboard](https://dashboard.voyageai.com) (Sec.[5](#5-recipes) has an example).\n\n**Figure 2.** A movie becomes an embedding, and the prediction model turns the embedding into a predicted rating.\n\nWe fit the model to the 17,527 movies released before 2010, predicted the IMDb rating of the 5,914 released from 2010 on, and compared the predictions with the actual ratings.\n\n- Always guessing the average rating of the older movies is off by 0.76 rating points on average.\n- `$predict` , reading the title, year, runtime, age rating, genres, cast, directors and plot of each movie, is off by\n0.68 points on average, and predicts 78% of movies within one point of their actual rating (72% for the guess).\n- Once the embeddings were computed, fitting took 79 seconds and `$predict` rated all 5,914 movies in\n8 seconds, on 16 CPU threads.\n\nTable [1](#tab-1) shows the most voted recent movies. Most of their predictions are too low: a model fit to minimise the\naverage error rarely predicts extreme values, so movies rated far above average are underestimated.\n\n**Table 1.** The eight most voted movies from 2010 on: actual and predicted IMDb ratings.\n\n| Movie | Actual | Predicted | \n|---|---|---|\n| Inception (2010) | 8.8 | 7.7 | \n| The Dark Knight Rises (2012) | 8.5 | 7.8 | \n| The Avengers (2012) | 8.1 | 6.1 | \n| Django Unchained (2012) | 8.5 | 6.8 | \n| Interstellar (2014) | 8.7 | 8.0 | \n| Shutter Island (2010) | 8.1 | 7.2 | \n| The Hunger Games (2012) | 7.3 | 7.4 | \n| The Wolf of Wall Street (2013) | 8.2 | 7.5 | \n\nThe same idea was tested on 50 real prediction tasks (MongoDB's sample data, a public benchmark of tables with text,\nand datasets collected from the web), in a separate study that also trained Voyage embedding models for JSON\ndocuments, called voyage-json. Adding the embedding of the whole document to the raw fields (no embedding model)\nraised the average performance from 52.1 to 73.3 with voyage-json and to 70.0 with voyage-4-nano (the general Voyage\nmodel mongo-predict uses by default, which runs on your own machine). Six embedding models not made by Voyage, from\n23 million to 8 billion parameters, reach 62.9 to 70.8 (Fig. [3](#fig-3)). Counting the error as 100 minus the\nperformance, voyage-json makes 44% fewer errors than the raw fields, voyage-4-nano 37%, and the other models 23% to\n39%.\n\n**Figure 3.** Average performance over 50 tasks (AUROC for classification, R² for regression,\n× 100; higher is better). Each bar adds that model's embedding of the whole document to the raw fields, which score\n52.1 alone; bars start at 60 and parameter counts are in parentheses. mongo-predict uses voyage-4-nano by default and\ncan use any Voyage model; voyage-json is the model trained for JSON in that study.\n\nThe same study compared against TypeSafe AI's Jev, a general model that labels documents without learning from your\nown data, on the 29 tasks that predict a category. The score used is AUROC, which runs from 50 (no better than a coin\nflip) to 100 (always right). Learning from the collection's own labelled documents with voyage-json scores 88.3\nagainst Jev's 77.6, which is 48% fewer errors, at a slightly lower price per token ($0.040 per million tokens,\nagainst $0.042) (Fig. [4](#fig-4)).\n\n**Figure 4.** Accuracy and price against Jev on the 29 classification tasks of the same study. Jev needs no labelled\ndocuments; learning from them means embedding those documents once (about $4 for a collection of 100 million\ntokens with voyage-json).\n\n## Reproducing these results\n\n- Fig. [1](#fig-1) , the movie results in Sec.[4](#4-results) and Table[1](#tab-1) :[`demos/predictions_api/movie_ratings.py`](https://github.com/mishelsikder/mongo-predict/blob/main/demos/predictions_api/movie_ratings.py) , run on`sample_mflix.movies` (23,441 movies with an IMDb rating and a release year) with voyage-4-nano embeddings; the\nresults are in[`results/writeup_movies.json`](https://github.com/mishelsikder/mongo-predict/blob/main/results/writeup_movies.json) . The other ratings stored in the\ndocuments (Rotten Tomatoes, Metacritic, awards, IMDb votes) are not used. The prediction model is XGBoost (the\ndefault). The times are on 16 CPU threads, with a cache of embeddings computed beforehand (one GPU minute for all\nmovies).\n- Fig. [3](#fig-3) : a Voyage study of the voyage-json models (50 evaluation tasks, 5,000 documents each, three random splits, ridge regression on\nthe fields plus the embedding; performance is AUROC × 100 for classification and R² × 100 for regression, averaged\nover the tasks). The voyage-json performance numbers here and in Fig.[4](#fig-4) are those of voyage-json-lite in\nthat study.\n- Fig. [4](#fig-4) : the same study (AUROC on its 29 classification tasks and prices per 1M tokens); 48% fewer errors is\n1 - (100 - 88.3) / (100 - 77.6).\n\nThe predictions are part of a normal pipeline, so the usual stages work on them.\n\n## **Rate the movies that have no rating and save the result**\n\n```\nmovies.aggregate([\n    {\"$predict\": {\"model\": \"imdb_rating\", \"filter\": {\"imdb.rating\": {\"$not\": {\"$type\": \"number\"}}}}},\n    {\"$project\": {\"predicted_rating\": {\"$meta\": \"prediction\"}}},\n    {\"$merge\": {\"into\": \"movies\", \"on\": \"_id\", \"whenMatched\": \"merge\"}},\n])\n```\n\n## **Find the biggest surprises**\n\n```\nmovies.aggregate([\n    {\"$predict\": {\"model\": \"imdb_rating\",\n                  \"filter\": {\"year\": {\"$gte\": 2010}, \"imdb.rating\": {\"$type\": \"number\"}}}},\n    {\"$set\": {\"surprise\": {\"$subtract\": [\"$imdb.rating\", {\"$meta\": \"prediction\"}]}}},\n    {\"$sort\": {\"surprise\": -1}},                  # rated much higher than expected\n    {\"$limit\": 10},\n    {\"$project\": {\"title\": 1, \"imdb.rating\": 1, \"surprise\": 1}},\n])\n```\n\n## **Average predicted rating per genre**\n\n```\nmovies.aggregate([\n    {\"$predict\": {\"model\": \"imdb_rating\", \"filter\": {\"year\": {\"$gte\": 2010}}}},\n    {\"$set\": {\"predicted\": {\"$meta\": \"prediction\"}}},\n    {\"$unwind\": \"$genres\"},\n    {\"$group\": {\"_id\": \"$genres\", \"predicted\": {\"$avg\": \"$predicted\"}, \"movies\": {\"$sum\": 1}}},\n    {\"$sort\": {\"predicted\": -1}},\n])\n```\n\n## **Use a Voyage API model instead of a local one**\n\n```\n# export VOYAGE_API_KEY=... first\nmovies.create_prediction_model(PredictionModel(\n    {\n        \"target\": \"imdb.rating\",\n        \"embedFields\": [\"title\", \"year\", \"runtime\", \"rated\", \"genres\", \"cast\", \"directors\", \"plot\"],\n        \"embeddingModel\": \"voyage-4-lite\",                 # or \"voyage-4\", \"voyage-4-large\", ...\n        \"embeddingKwargs\": {\"output_dimension\": 1024},     # 256, 512, 1024 or 2048\n        \"filter\": {\"year\": {\"$lt\": 2010}},\n    },\n    name=\"imdb_rating_api\",\n))\n```\n\nRequests are batched within the API's limits and retried with backoff when the rate limit is reached; `$predict`\nembeds the new documents through the API as well.\n\n## **Check, refit or remove a model**\n\n```\nmovies.list_prediction_models(\"imdb_rating\")    # status, settings, accuracy on held-out movies\nmovies.update_prediction_model(\"imdb_rating\", {...new settings...})   # the old version keeps answering meanwhile\nmovies.drop_prediction_model(\"imdb_rating\")\n```\n\n- A model predicts a number or a category. With `\"task\": \"auto\"` (the default), a field of numbers with at least 8\ndistinct values is predicted as a number, and anything else as a category.\n- The model learns only from documents where the field is set. Its accuracy on documents it was not fit to is stored\nwith it (`list_prediction_models` ).\n- Embedding is the slow step: about a minute for the 23,478 rated movies on one GPU, and much longer on a CPU. The embeddings are cached, so refitting on the same documents takes seconds.\n- `$predict` runs from Python and must be the first stage of a pipeline. It reads the matching documents into your\nprogram, so use a filter or a limit on a large collection.\n- It needs MongoDB 5.0 or later (tested on 5.0, 6.0, 7.0 and 8.0, and on Atlas; older servers get a clear error), and permission to create and drop collections in the database (for a temporary collection that holds the predictions).\n- Models are stored in the `__mongopredict_models` collection and loaded by the programs that use them, so only\ntrusted users should be able to write to it.\n\nThe predictions API documentation covers the rest: the [model definition](https://github.com/mishelsikder/mongo-predict/blob/main/docs/pymongopredict/predictions_api.html#model-definition) (every setting),\n[how a pipeline runs](https://github.com/mishelsikder/mongo-predict/blob/main/docs/pymongopredict/predictions_api.html#how-a-pipeline-runs), and [details and limits](https://github.com/mishelsikder/mongo-predict/blob/main/docs/pymongopredict/predictions_api.html#details-and-limits) (permissions,\nsigned models, views and time-series collections, cleanup of temporary collections, label types and missing values).\n\n`$predict` is built on an API in the style of scikit-learn that turns MongoDB documents into feature matrices. Use it\nto choose the model yourself, to cross-validate, to add other features or to forecast time series. `MongoDataset`\npoints at a collection and indexes like an array, so scikit-learn's `train_test_split`, cross-validation splitters\nand `cross_val_score` work on it directly; `DocumentFeaturizer` is a scikit-learn transformer that returns the\nembedding of each document:\n\n``` python\nfrom sklearn.linear_model import RidgeCV\nfrom sklearn.model_selection import train_test_split\nfrom pymongopredict import DocumentFeaturizer, MongoDataset\n\nds = MongoDataset(movies, target=\"imdb.rating\", sort=[(\"released\", 1)],          # oldest first\n                  filter={\"imdb.rating\": {\"$type\": \"number\"}, \"released\": {\"$type\": \"date\"}})\nds_train, ds_test = train_test_split(ds, test_size=0.2, shuffle=False)          # newest 20% as test\nprep = DocumentFeaturizer(\n    embed_fields=[\"title\", \"year\", \"runtime\", \"rated\", \"genres\", \"cast\", \"directors\", \"plot\"],  # None: everything\n    embedding_model=\"voyage-4-nano\",                                 # or another Voyage model\n)\nreg = RidgeCV().fit(prep.fit_transform(ds_train), ds_train.y)\nreg.score(prep.transform(ds_test), ds_test.y)    # R² on the newest movies\n```\n\nThe featurizer works in a `Pipeline`, accepts cursors and lists of documents, caches embeddings and can read\ndocuments in batches. `MongoSeries` builds time series for sktime forecasters. A model behind `$predict` is this\nfeaturizer plus a scikit-learn estimator, set with `\"estimator\"` in the model definition. The\n[embeddings API documentation](https://github.com/mishelsikder/mongo-predict/blob/main/docs/pymongopredict/embeddings_api.html) describes splits, featurizing, streaming,\nforecasting and the embedding models.\n\n- \n**Documentation:**[`docs/`](https://github.com/mishelsikder/mongo-predict/blob/main/docs/index.html) has one page for the package and one per API, built from the\ndocstrings with`bash docs/build_docs.sh` (open`docs/index.html` in a browser).\n- \n**Demos:**[`demos/`](https://github.com/mishelsikder/mongo-predict/blob/main/demos) runs each API on MongoDB's sample data; the[package documentation](https://github.com/mishelsikder/mongo-predict/blob/main/docs/pymongopredict.html) lists them with their results.\n\n```\nuv run python -m demos.load_sample_data --uri mongodb://localhost:27017 sample_mflix sample_airbnb sample_weatherdata\nuv run python -m demos.predictions_api.movie_ratings --uri mongodb://localhost:27017\n```\n\n- \n**Reports:**[`reports/`](https://github.com/mishelsikder/mongo-predict/blob/main/reports/index.html) measures the speed of the embeddings API and the overhead and accuracy\nof`$predict` .\n- \n**Development:**\n\n```\nuv sync --all-extras --group dev\nuv run pytest -n 4                                              # tests on mongomock, no network or GPU needed\nMONGOPREDICT_TEST_URI=mongodb://localhost:27017 uv run pytest   # also the tests against a real server\nuv run ruff check .\n```\n\nMIT", "url": "https://wpnews.pro/news/mongo-predict-create-your-own-jev", "canonical_source": "https://github.com/mishelsikder/mongo-predict", "published_at": "2026-10-26 15:56:21+00:00", "updated_at": "2026-10-26 16:11:38.596946+00:00", "lang": "en", "topics": ["ai-tools", "machine-learning", "developer-tools", "ai-products"], "entities": ["Voyage AI", "mongo-predict", "pymongopredict", "MongoDB", "XGBoost", "scikit-learn", "Jev", "sample_mflix.movies"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/mongo-predict-create-your-own-jev", "markdown": "https://wpnews.pro/news/mongo-predict-create-your-own-jev.md", "text": "https://wpnews.pro/news/mongo-predict-create-your-own-jev.txt", "jsonld": "https://wpnews.pro/news/mongo-predict-create-your-own-jev.jsonld"}}