简体   繁体   English

光学 API:如何获得具有最大值的列的值?

[英]Optic API: how do I get the value of a column that goes with a max value?

My data set has two arrays holding objects with two properties, a date and a value.我的数据集有两个 arrays 持有具有两个属性的对象,一个日期和一个值。 For each array, I need to get the object that has the most recent date.对于每个阵列,我需要获取最新日期的 object。 I'm trying to do this from indexes and am exploring using the Optic API for the query.我正在尝试从索引中执行此操作,并正在探索使用光学 API 进行查询。

My view has three columns: "statusType", which indicates which array the values come from;我的视图有三列:“statusType”,表示值来自哪个数组; "statusDate"; “状态日期”; and "value".和“价值”。 With the following query, I can get the most recent date for each type, but I don't see how I can get the value that goes with it.通过以下查询,我可以获得每种类型的最新日期,但我不知道如何获得与之相关的值。

const op = require('/MarkLogic/optic');

op.fromView('Parent', 'info')
  .where(cts.documentQuery('/test/doc1.json'))
  .groupBy([op.col('statusType')], [op.max('maxdate', op.col('statusDate'))])
  .result()

Produces:产生:

{
  "statusType": "subtype1", 
  "maxdate": "2020-09-29T16:33:18.6301434-04:00"
},
{
  "statusType": "subtype2", 
  "maxdate": "2020-08-29T16:33:18.6301434-04:00"
}

If I add value to the first parameter to groupBy , I get all distinct combinations of type and value (with the maxdate).如果我将value添加到groupBy的第一个参数,我会得到类型和值的所有不同组合(使用 maxdate)。 If I add value to the second parameter to groupBy , I get the last value, not the one associated with the maxdate .如果我将value添加到groupBy的第二个参数,我会得到最后一个值,而不是与maxdate关联的值。

Expected output:预期 output:

{
  "statusType": "subtype1", 
  "value": "valueB",
  "maxdate": "2020-09-29T16:33:18.6301434-04:00"
},
{
  "statusType": "subtype2", 
  "value": "valueC",
  "maxdate": "2020-08-29T16:33:18.6301434-04:00"
}

Sample data:样本数据:

'use strict';
declareUpdate();

xdmp.documentInsert(
  '/test/doc1.json',
  {
    "parent": {
      "subtype1": [
        {
          "value": "valueA", 
          "date": "2020-07-29T16:33:18.6301434-04:00"
        }, 
        {
          "value": "valueB", 
          "date": "2020-09-29T16:33:18.6301434-04:00"
        }
      ], 
      "subtype2": [
        {
          "value": "valueC", 
          "date": "2020-08-29T16:33:18.6301434-04:00"
        }, 
        {
          "value": "valueD", 
          "date": "2020-07-29T16:33:18.6301434-04:00"
        }
      ]
    }
  }
)

Template 1:模板 1:

declareUpdate();
const tde = require("/MarkLogic/tde.xqy");

let template = 
  xdmp.toJSON(
    {
      "template": {
        "context": "/parent/subtype1",
        "rows": [
          {
            "schemaName": "Parent",
            "viewName": "info",
            "columns": [
              {
                "name": "statusType",
                "scalarType": "string",
                "val": "'subtype1'"
              },
              {
                "name": "value",
                "scalarType": "string",
                "val": "value"
              },
              {
                "name": "statusDate",
                "scalarType": "dateTime",
                "val": "date"
              }
            ]
          }
        ]
      }
    }
  );

// comment and uncomment based on which action you want to take
let action = 
  //'validate'
  //'extract'
  'insert'
;

if (action === 'validate') {
  tde.validate([template]);
} else if (action === 'extract') {
  tde.nodeDataExtract([cts.doc( "/test/doc1.json" )],  [template])
} else if (action === 'insert') {
  tde.templateInsert("/tde/subtype1.json", template, xdmp.defaultPermissions(), ["TDE"])
}

Template 2:模板 2:

declareUpdate();
const tde = require("/MarkLogic/tde.xqy");

let template = 
  xdmp.toJSON(
    {
      "template": {
        "context": "/parent/subtype2",
        "rows": [
          {
            "schemaName": "Parent",
            "viewName": "info",
            "columns": [
              {
                "name": "statusType",
                "scalarType": "string",
                "val": "'subtype2'"
              },
              {
                "name": "value",
                "scalarType": "string",
                "val": "value"
              },
              {
                "name": "statusDate",
                "scalarType": "dateTime",
                "val": "date"
              }
            ]
          }
        ]
      }
    }
  );

// comment and uncomment based on which action you want to take
let action = 
  //'validate'
  //'extract'
  'insert'
;

if (action === 'validate') {
  tde.validate([template]);
} else if (action === 'extract') {
  tde.nodeDataExtract([cts.doc( "/test/doc1.json" )],  [template])
} else if (action === 'insert') {
  tde.templateInsert("/tde/subtype2.json", template, xdmp.defaultPermissions(), ["TDE"])
}

Salutations, Mr Cassel:问候,卡塞尔先生:

If I understand the requirement correctly, the only approach that I know is to join the groupBy() result with the original view:如果我正确理解了要求,我知道的唯一方法是将groupBy()结果与原始视图一起加入:

  1. The groupBy() emits rows with the grouping key and max() aggregate values, passing an alias / qualifier name on the fromView() accessor. groupBy()发出具有分组键和 max() 聚合值的行,在fromView()访问器上传递别名/限定符名称。
  2. Get the rest of the columns for the max row by joining with the same view (with join keys on maxInfo.statusType=info.statusType and maxInfo.maxdate=info.statusDate).通过连接相同的视图(在 maxInfo.statusType=info.statusType 和 maxInfo.maxdate=info.statusDate 上使用连接键)获取最大行列的 rest。

The groupBy() operation samples any column in the aggregates argument. groupBy()操作对聚合参数中的任何列进行采样。

Hoping that helps,希望有帮助,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM