Mongodb 聚合失败:“FieldPath 字段名称不能以‘$’开头。”

时间:2021-03-07 05:31:51

标签: mongodb aggregation-framework

我正在尝试找出这段代码失败的原因:

db.restaurants.drop();

db.restaurants.insertMany( [
  { "_id" : 1, "borough" : "Manhattan"},
] );

db.restaurants.createIndex({
  "borough": "text"
})

db.restaurants.aggregate([
  { $match: { $text: { $search: "a" } } },
  { $sort: {score: {"$meta": "textScore"}}},
  { $project: {"_id": true}},
])

错误输出:

uncaught exception: Error: command failed: {
        "ok" : 0,
        "errmsg" : "FieldPath field names may not start with '$'.",
        "code" : 16410,
        "codeName" : "Location16410"
} : aggregate failed :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
doassert@src/mongo/shell/assert.js:18:14
_assertCommandWorked@src/mongo/shell/assert.js:639:17
assert.commandWorked@src/mongo/shell/assert.js:729:16
DB.prototype._runAggregate@src/mongo/shell/db.js:266:5
DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1058:12
@(shell):1:1

我知道这与项目声明有关...

先谢谢你!

-丹尼尔

1 个答案:

答案 0 :(得分:3)

您的问题几乎与此 Mongodb 4.4.0 FieldPath field names may not start with 相似,我有 answered 解决方案,唯一的区别是投影字段和一些用例!

经过大量研究,我在投影中的使用部分下找到了以下关于查找和聚合函数text-score-metadata-meta-textscore的一般说明,

<块引用>

{ $meta: "textScore" } 表达式可以是投影文档的一部分,以包含文本分数元数据。

$meta 表达式可以出现在包含或排除投影中。

如果您将表达式设置为文档中已存在的字段名称,则投影的元数据值将覆盖现有值。

粗体句上方清除,如果您在 $project 阶段之后使用 $sort 阶段,score 或文本索引字段 borough包含或排除,

根据您尝试的解决方案:

db.restaurants.aggregate([
  { $match: { $text: { $search: "a" } } },
  { $sort: { score: { "$meta": "textScore" } } },
  { 
    $project: {
      "_id": true, // or _id: 1
      "borough": false // or borough: 0
    }
  },
  // or by default _id would be included
  /*
  { 
    $project: {
      "borough": false // or borough: 0
    }
  },
  */
  // or below will work but this will work as exclusion projection, so you need to specify your other fields to exclude,
  /* 
  { 
    $project: {
      "_id": true, // or _id: 1
      "score": false, // or score: 0
    }
  }
  */
  // or by default _id would be included
  /*
  { 
    $project: {
      "score": false, // or score: 0
    }
  },
])

还有其他方式,我会推荐这种方式

  • 交换 $project$sort 阶段,
db.restaurants.aggregate([
  { $match: { $text: { $search: "a" } } },
  { $project: { "_id": true } },
  { $sort: { score: { "$meta": "textScore" } } }
])
相关问题