我如何在MongoDB $ projection中使用$ map

时间:2019-02-01 19:18:40

标签: python arrays mongodb aggregation-framework

我有一个包含以下文档的数据库:

  @Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    viewModel = ViewModelProviders.of(getActivity()).get(LinesViewModel.class);

    viewModel.getLastLinesUpdate().observe(this, dateTime -> {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.YYYY HH:mm:ss");
        linesLastUpdate.setText(dateTime.format(formatter));
    });
}

现在我的目标是检索所有文件,但{ _id: 123, metrics: [{ _id: ObjectID(…), name: 'foo', steps: [1, 2, 3, …], values: [10, 12, 13, …] }, { _id: ObjectID(…), name: 'bar', steps: [1, 2, 3, …], values: [1.2, 1.2, 1.3, …] }, ] } 的所有数组项到其$map属性,丢弃等领域。我以为我可以这样:

name

但是每个数组项(pipeline = [{'$project': {'metrics': {'$map': {'input': '$metrics', 'in': '$this.name'}] results = client.db.runs.aggregate(pipeline) )的结果只有None个值,就好像请求的字段{'metrics': [None, None, None, …]}不存在一样。但是确实如此。我也尝试过使用id字段,但无济于事。我可以在检查数据时看到字段所在。我无法弄清楚我在做什么错。

1 个答案:

答案 0 :(得分:1)

$map内,您可以使用as定义临时变量,该变量将代表metrics中的单个文档,然后在in部分中引用该变量。

db.col.aggregate([{'$project': {'metrics': {'$map': {'input': '$metrics', as: 'metric', 'in': '$$metric.name' } } } }])

或者您可以直接引用临时变量this

db.col.aggregate([{'$project': {'metrics': {'$map': {'input': '$metrics', 'in': '$$this.name' } } } }])

问题是,每次使用单个美元符号时,您都引用在当前管道阶段正在处理的文档中定义的字段。此外,您可以使用双美元符号来引用一些可由$map$filter等运算符定义的变量。

您可以尝试以下文档的初始代码:

{
    _id: 123, 
    this: { name: "x" },
    metrics: [{ }, { } ]
}

,您将获得一个包含两个x值的数组,因为有两个度量,但是每次迭代都引用相同的this.x值:

{ "_id" : 123, "metrics" : [ "x", "x" ] }