CouchDB 显示不同的值

CouchDB display distinct values

我有如下文档,

 {
     "id": "7d9fdc2f4846544d62da3421bf011b31",
     "al": [
       { "id16": "0x1d42",
         "pos": {
                "x": 10.32,
                "y": 11.13,
                "z": 1.22
                },
           "resultTime": "2020-06-01T20:45:34.976Z"
       },
      { "id16": "0x1342",
          "pos": {
                "x": 0.32,
                "y": 1.13,
                 "z": 13.22
                 },
        "resultTime": "2021-06-01T20:45:34.976Z"
      }
     .
     .
     .
     ],
      "Timestamp": 272179,
      "Oid": "Onion1",
     
    }

设计文档如下

{
 "id": "_design/GetALwithAnchorID",
 "key": "_design/GetALwithAnchorID",
 "value": {
  "rev": "32-6db6c4e105336d47a6c8e7e8458ee345"
 },
 "doc": {
  "_id": "_design/GetALwithAnchorID",
  "_rev": "32-6db6c4e105336d47a6c8e7e8458ee345",
  "views": {
   "GetALwithAnchorID": {
    "map": "function (doc) {\n\n  for (var i=0; i<doc.al.length; i++) { \n    emit(doc.al[i].id16, doc.al[i].pos);\n    }\n    \n}\n\n",
    "reduce": "_approx_count_distinct"
   }
  },
  "language": "javascript"
 }
}

当我像这样查询视图时

http://127.0.0.1:5984/rtls/_design/GetALwithAnchorID/_view/GetALwithAnchorID?group_level=1&key=%220x1d42%22

我得到的结果如下

{"rows":[
{"key":"0x1d42","value":1}
]}

但我想要 id16 的不同值和 id16 的位置。并按时间对这些不同的值进行排序,并在 Iquery?

时显示 pos 的值而不是 "value":1

提前致谢。

好吧,所以和这个不太一样。遇到此问题的任何人 Q/A,我建议阅读该答案。

为给定的文档结构考虑以下 emit

doc.al.forEach(e => emit(
  [e.pos.x, e.pos.y, e.pos.z, e.resultTime], // key
  [e.id16, e.pos, e.resultTime]) // value
));    

   

索引中可视化的 emit 的复杂键(松散地不是逐字的):

[-3,-2,-1,"2017-10-28T22:56:58.852Z"]
[-3,-2,-1,"2019-01-23T03:33:20.958Z"] **
. . .
[0,0,0,"2016-05-27T01:38:36.305Z"]
[0,0,0,"2016-12-27T05:17:02.255Z"] **
. . .
[1,2,3,"2016-11-14T17:31:59.468Z"]
[1,2,3,"2017-07-17T07:52:38.180Z"] **

其中每个 ** 都是 pos 组中的最后一项,并且显着 最近的 resultTime。一切归功于 CouchDB 的整理。

使用 CouchDB 需要了解 B 树,它的文档在其 Reduce/Rereduce 文档中有一个很好的概述。

现在考虑这个 reduce 函数:

function(keys,values,rereduce) {               
   return values[0];
}

它看起来不是很令人印象深刻,但进一步考虑使用这些参数调用视图:

{
    reduce: true,
    group_level: 1,
    descending: true
}

通过使用 descending 反转索引扫描的顺序,reduce 函数保证 return 相对于任何给定 resultTime 的最新行 pos组。

这是一个使用 pouchDB 的简单演示。它生成 6 个随机 resultTime 的文档,并从 3 个文档中随机选择 pos。看看设计文档。

async function showReduceDocs(view) {
  let result = await db.query(view, {
    reduce: true,
    group_level: 1,
    descending: true
  });
  // show   
  debugger;
  gel('view_reduce').innerText = result.rows.map(row => `${JSON.stringify(row.value)}`.split(',').join(', ')).join('\n');

  return result;
}

async function showViewDocs(view) {
  let result = await db.query(view, {
    reduce: false,
    include_docs: false
  });
  //show   
  gel('view_docs').innerText = result.rows.map(row => JSON.stringify(row.key))
    .join('\n');
}

function getDocsToInstall(count) {
  // design document
  const ddoc = {
    "_id": "_design/SO-66231293",
    "views": {
      "id16": {
        "map": `function (doc) {          
           doc.al.forEach((e) => emit([e.pos.x, e.pos.y, e.pos.z, e.resultTime],[e.id16, e.pos, e.resultTime]));           
        }`,
        "reduce": `function(keys,values,rereduce) {               
           return values[0];
        }`
      }
    }
  };

  // create a set of random documents.
  let docs = new Array(count);
  let docId = 65;
  const posSeed = [{
      x: 0,
      y: 0,
      z: 0
    },
    {
      x: 1,
      y: 2,
      z: 3
    },
    {
      x: -3,
      y: -2,
      z: -1
    }
  ];
  const dateSeed = [new Date(2000, 0, 1), new Date(), 0, 24];
  while (count--) {
    let n = 6;
    let doc = {
      _id: String.fromCharCode(docId++),
      al: new Array(n)
    };

    while (n-- > 0) {
      doc.al[n] = {
        "id16": "0x000" + n,
        "pos": posSeed[Math.floor(Math.random() * 100) % 3],
        "resultTime": randomDate(...dateSeed).toISOString()
      };
    }

    docs[count] = doc;
  }

  docs.push(ddoc);
  return docs;
}

const db = new PouchDB('SO-66231293', {
  adapter: 'memory'
});

(async() => {
  // install docs and show view in various forms.
  await db.bulkDocs(getDocsToInstall(6));
  gel('content').classList.remove('hide')
  showReduceDocs('SO-66231293/id16');
  showViewDocs('SO-66231293/id16');
})();

const gel = id => document.getElementById(id);

/*

*/
function randomDate(start, end, startHour, endHour) {
  var date = new Date(+start + Math.random() * (end - start));
  var hour = startHour + Math.random() * (endHour - startHour) | 0;
  date.setHours(hour);
  return date;
}
<script src="https://cdn.jsdelivr.net/npm/pouchdb@7.1.1/dist/pouchdb.min.js"></script>
<script src="https://github.com/pouchdb/pouchdb/releases/download/7.1.1/pouchdb.memory.min.js"></script>
<div id='content' class='hide'>
  <div>View: reduce</div>
  <pre id='view_reduce'></pre>
  <hr/>
  <div>View: complex key</div>
  <pre id='view_docs'></pre>
</div>

编辑 根据 OP 的评论修改了演示片段。