【问题标题】:Mongodb 4.4.0 FieldPath field names may not start withMongodb 4.4.0 FieldPath 字段名称可能不以
【发布时间】:2020-11-27 12:02:01
【问题描述】:

我只是浏览有关 mongodb 的文档并尝试使用聚合,当我的查询包含 { $project: { aw_product_id: 1, _id: 0} } 部分时出现错误,$project 部分一切看起来正确,列 aw_product_id 出现在我的模型中,我尝试更改为另一列,但仍然面临同样的错误。我做错了什么?

db.version() -> 4.4.0

db.getCollection('AwinProduct').aggregate(
   [
     { $match: { $text: { $search: "Sko Nike Classic Cortez för män -Svart", $language: 'sv'  } } },
     { $sort: { score: { $meta: "textScore" } } },
     { $project: { aw_product_id: 1, _id: 0} }
   ]
)

面对这个问题

无法执行脚本。

Error: command failed: {
    "ok" : 0,
    "errmsg" : "FieldPath field names may not start with '$'.",
    "code" : 16410,
    "codeName" : "Location16410"
} : aggregate failed 
Details:
_getErrorWithCode@src/mongo/shell/utils.js:25:13
doassert@src/mongo/shell/assert.js:18:14
_assertCommandWorked@src/mongo/shell/assert.js:534:17
assert.commandWorked@src/mongo/shell/assert.js:618:16
DB.prototype._runAggregate@src/mongo/shell/db.js:260:9
DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1062:12
DBCollection.prototype.aggregate@:1:355
@(shell):1:1

我对另一个收藏和新收藏做了同样的事情,但遇到了同样的错误

我尝试对字段使用 qoutes 但仍然是同样的错误

db.getCollection('AwinProduct').aggregate(
   [
     { $match: { $text: { $search: "Sko Nike Classic Cortez för män -Svart", $language: 'sv'  } } },
     { $sort: { score: { $meta: "textScore" } } },
     { $project: { "currency": 1, _id: 0} }
   ]
)

我在 docker 结构中使用 mongo,这是我为这个 img 编写的 docker-compose

mongodb:
    image: mongo:latest
    container_name: mongodb
    hostname: mongodb
    volumes:
        - ./docker/mongodb/mongod.conf:/etc/mongod.conf
        - ./docker/mongodb/initdb.d/:/docker-entrypoint-initdb.d/
        - ./data/momgo/:/data/db/
        - ./docker/mongodb/data/log/:/var/log/mongodb/
        - ./docker/mongodb/home:/home/mongodb
    env_file:
        - .env
    environment:
        MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
        MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
        MONGO_INITDB_DATABASE: ${MONGO_INITDB_DATABASE}
    ports:
        - "27017:27017"
    command: ["-f", "/etc/mongod.conf"]
    networks:
        - php

【问题讨论】:

  • 尝试用引号将aw_product_id 括起来。一个猜想。查询对我来说看起来不错。
  • @Gibbs 双引号和单引号无济于事 :( 一些魔法......

标签: mongodb aggregation-framework


【解决方案1】:

我遇到了同样的问题,我可能有一些解决方案。 $sort 运算符似乎有问题。试着把它放在你的 $project 操作符之后。

在我的情况下,以下管道存在相同的错误:$sort,然后是 $unwind,然后是 $project。如果将 $sort 放在 $unwind 之后,无论 $unwind 是否放在 $project 之后,错误都会消失。

我不完全理解这种情况,但是当涉及第三个运算符时,$sort 和 $project 之间似乎存在一些模糊的交互。

【讨论】:

    【解决方案2】:

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

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

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

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

    上面的粗体句清除,如果您在$sort 阶段之后使用$project 阶段,则您创建的文本索引的score 或文本索引字段应该是包含或排除,

    根据您的尝试解决方案:

    我没有文本索引字段名称,但我会预测字段名称为name

    db.getCollection('AwinProduct').createIndex({ name: "text" });
    
    db.getCollection('AwinProduct').aggregate(
       [
         { $match: { $text: { $search: "Sko Nike Classic Cortez för män -Svart", $language: 'sv'  } } },
         { $sort: { score: { $meta: "textScore" } } },
         { 
           $project: { 
             "_id", "$$REMOVE",
             "name": "$$REMOVE",
             "aw_product_id": 1
         }
       ]
    )
    

    除了@Alexandre Masseron's answer,还有其他方式,我会推荐这种方式

    • 交换$project$sort舞台,
    db.getCollection('AwinProduct').aggregate(
       [
         { $match: { $text: { $search: "Sko Nike Classic Cortez för män -Svart", $language: 'sv'  } } },
         { $project: { aw_product_id: 1, _id: 0 } },
         { $sort: { score: { $meta: "textScore" } } }
       ]
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-16
      • 1970-01-01
      • 2017-09-27
      • 2015-06-25
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      相关资源
      最近更新 更多