【问题标题】:querying part of array key in couchDB view在 couchDB 视图中查询部分数组键
【发布时间】:2017-02-22 02:21:56
【问题描述】:

我目前有一个名为 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]

但是,这会返回给我相当随机的结果,其中也包括其他的 beaconUUID。

我对这个冗长的解释的问题是:鉴于键是一个数组,有没有办法查询数组的值之一,例如

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

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

【问题讨论】:

    标签: couchdb cloudant nosql


    【解决方案1】:

    使用这个视图

    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 来找到这个答案!谢谢!
    【解决方案2】:

    您是否考虑过使用Cloudant query

    定义索引

    POST /$DATABASE/_index HTTP/1.1
    
    { 
     "index": {
       "fields": [
        "beaconUUID",
        "timestamp"
       ]
     },
     "type": "json"
    }
    

    ...并查询它

    POST /$DATABASE/_find HTTP/1.1
    

    在 BODY 中传递查询

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

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

    【讨论】:

    【解决方案3】:

    对于其他寻找此问题替代方案的人,以下是我关于 _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-On-Couch

    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);
    

    【讨论】:

      猜你喜欢
      • 2013-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-24
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      相关资源
      最近更新 更多