在 couchDB 视图中查询数组键的一部分

querying part of array key in couchDB view

我目前有一个名为 beacon_logs 的文档,每次我走进信标范围时它都会记录下来。数据看起来类似于:

{
  "_id": "00198cd8f0fc510dbad06bf24e93f55b",
  "_rev": "1-e90f025935847b0412923e4ba472cf2a",
  "device": "gwen",
  "beaconUUID": "123",
  "distance": "0.0",
  "timestamp": 1487443924
},
{
  "_id": "00198cd8f0fc510dbad06bf24e93f55c",
  "_rev": "1-e90f025935847b0412923e4ba472cf2a",
  "device": "gwen",
  "beaconUUID": "123",
  "distance": "0.1",
  "timestamp": 1487443925
},
{
  "_id": "01ab15fd3a1c7c37ba147be8c56fe389",
  "_rev": "1-587035fb7a71962c21f91b86aca56a77",
  "device": "gwen",
  "beaconUUID": "456",
  "distance": "0.87",
  "timestamp": 1487031602
},
{
  "_id": "01ab15fd3a1c7c37ba147be8c56fe388",
  "_rev": "1-587035fb7a71962c21f91b86aca56a77",
  "device": "gwen",
  "beaconUUID": "456",
  "distance": "0.87",
  "timestamp": 1487031603
}

而这个观点:

function (doc) {
  emit([doc.beaconUUID,doc.timestamp], doc);
}

我想要的是只获取某个 beaconuuid(即 123)的所有内容,并让它也按时间戳排序。这是我写的查询:

*DB_NAME*/_design/*DDOC_NAME*/_view/*VIEW_NAME*?descending=false&startkey=["123",999999999]&endkey=["123",0]

然而,这个 returns 我非常随机的结果,其中也包括其他 beaconUUID。

我对这个冗长的解释的问题是:鉴于键是一个数组,是否有任何方法可以查询数组的值之一,例如

*DB_NAME*/_design/*DDOC_NAME*/_view/*VIEW_NAME*?descending=false&key[0]="123"

如果没有,有人可以推荐解决方法吗?

您是否考虑过使用 Cloudant query

定义索引

POST /$DATABASE/_index HTTP/1.1

{ 
 "index": {
   "fields": [
    "beaconUUID",
    "timestamp"
   ]
 },
 "type": "json"
}

...并查询

POST /$DATABASE/_find HTTP/1.1

在正文中传递查询

{
 "selector": {
  "beaconUUID": {
   "$eq": "123"
  }
 },
 "sort": [
   "beaconUUID",
   "timestamp"
 ]
}

P.S。如果您想知道为什么 beaconUUID 包含在排序定义中,请参阅 Cloudant: How to create an index for "Sort" function?

使用此视图

function (doc) {
  if (doc.beaconUUID) {
    emit([doc.beaconUUID,doc.timestamp], doc);
  }
}

我能够通过这些查询获得正确的响应:

时间戳顺序:
*DB_NAME*/_design/*DDOC_NAME*/_view/*VIEW_NAME*?startkey=["123",0]&endkey=["123",{}]

反向时间戳顺序:
*DB_NAME*/_design/*DDOC_NAME*/_view/*VIEW_NAME*?startkey=["123",{}]&endkey=["123",0]&descending=true

这里是我关于 _find 的发现。

_查找查询

{
    'selector': {
        'beaconUUID':'123'
    },
    'fields': ['beaconUUID', 'timestamp'],
    'sort': [
        {'beaconUUID':'desc'},
        {'timestamp':'desc'}
    ]
}

使用_find

通过 PHP CURL

$url = 'https://'.<ACCOUNTNAME>.'.cloudant.com/<DB_NAME>/_find';
$fields = array(
                'selector' => array('beaconUUID'=>"123"),
                'fields' => array("beaconUUID",
                                  "timestamp"),
                'sort' => array(array("beaconUUID"=>"desc"), 
                                array("timestamp"=>"desc"))
            );
$fields_string = json_encode($fields);
$ch = curl_init();  

    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_USERPWD, <APIKEY> . ":" . <APIPASSWORD>);       
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");                                                                  
    curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-type: application/json',
        'Accept: */*'
    ));

    $output=curl_exec($ch);

    curl_close($ch);
    echo $output;

通过 PHP-沙发上

require_once 'PHP-on-Couch/Couch.php';
require_once 'PHP-on-Couch/CouchAdmin.php';
require_once 'PHP-on-Couch/CouchClient.php';
require_once 'PHP-on-Couch/CouchDocument.php';
require_once 'PHP-on-Couch/CouchReplicator.php';
require_once 'PHP-on-Couch/Exceptions/CouchException.php';
require_once 'PHP-on-Couch/Exceptions/CouchConflictException.php';
require_once 'PHP-on-Couch/Exceptions/CouchExpectationException.php';
require_once 'PHP-on-Couch/Exceptions/CouchForbiddenException.php';
require_once 'PHP-on-Couch/Exceptions/CouchNoResponseException.php';
require_once 'PHP-on-Couch/Exceptions/CouchNotFoundException.php';
require_once 'PHP-on-Couch/Exceptions/CouchUnauthorizedException.php';


use PHPOnCouch\Couch, 
PHPOnCouch\CouchAdmin, 
PHPOnCouch\CouchClient;

$fullurl = 'http://'.<APIKEY>.':'.<APIPASSWORD>.'@'.<ACCOUNTNAME>.'.cloudant.com';
$client = new CouchClient($fullurl,$DATABASE);
$sort = [
            ["beaconUUID" => 'desc'],
            ["timestamp" => 'desc']
        ];
$fields = ['beaconUUID', 'timestamp'];
$find = ['beaconUUID'=>"123"];
$docs = $client->skip(10)->limit(30)->sort($sort)->fields($fields)->find($find);
echo json_encode($docs);