You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB投影title字段异常:需重复指定title:1才能生效?

MongoDB聚合投影字段丢失问题:原因与解决方法

Hey there, let's break down why you're seeing this odd behavior with your aggregation query and how to fix it cleanly.

Why does repeating title:1 work?

MongoDB's $project stage uses a whitelist approach by default. That means:

  • Only the fields you explicitly mark with 1 (or define new computed fields for) are carried over to the next pipeline stage.
  • The _id field is kept automatically unless you explicitly exclude it with _id:0.

In your query, the first $project includes title:1, so title makes it to the second stage. But your second $project only defines the normalized_rating computed field—you don't explicitly include title here. So MongoDB drops the title field (and any other unmentioned fields) before moving to the next stage. When you add title:1 again in the second $project, you're telling MongoDB to keep that field alongside the new computed one, which is why it shows up in your results.

Fixes to avoid repeating fields

You have two solid options to clean up this query:

1. Explicitly include needed fields in the second $project

If you want to keep the two separate $project stages, just add the fields you want to retain to the second stage:

db.movies.aggregate([
  {$match: { 
    languages: {$elemMatch : {$eq: "English"}}, 
    "imdb.rating":{$gte: 1}, 
    "imdb.votes":{$gte: 1}, 
    year: {$gte: 1990} 
  }},
  {$project: {
    scaled_votes: {$add: [
      1, 
      {$multiply: [
        9, 
        {$divide: [
          {$subtract: ["$imdb.votes",5]},
          {$subtract: [1521105,5]}
        ]}
      ]}
    ]}, 
    "imdb.rating": 1, 
    title: 1 
  }},
  {$project: {
    normalized_rating: {$avg: ["$scaled_votes", "$imdb.rating"]},
    title: 1, // Keep title
    "imdb.rating": 1 // Keep rating if needed
  }}
])

2. Merge both $project stages into one (more efficient)

There's no need to split the projection and computed fields into two separate stages. Combining them reduces pipeline overhead and eliminates the need to repeat field definitions:

db.movies.aggregate([
  {$match: { 
    languages: {$elemMatch : {$eq: "English"}}, 
    "imdb.rating":{$gte: 1}, 
    "imdb.votes":{$gte: 1}, 
    year: {$gte: 1990} 
  }},
  {$project: {
    title: 1,
    "imdb.rating": 1,
    scaled_votes: {$add: [
      1, 
      {$multiply: [
        9, 
        {$divide: [
          {$subtract: ["$imdb.votes",5]},
          {$subtract: [1521105,5]}
        ]}
      ]}
    ]},
    normalized_rating: {$avg: ["$scaled_votes", "$imdb.rating"]}
  }}
])

This single $project stage computes both scaled_votes and normalized_rating while retaining the title and imdb.rating fields you need, all in one step.

内容的提问来源于stack exchange,提问作者Rahul Raj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:22:22