如何在Cloudant查询结果中省略嵌套对象中的字段?

时间:2017-06-01 12:44:34

标签: indexing couchdb ibm-cloud cloudant nosql

我用Google搜索并试图解决这个问题,似乎这是不可能的。也许(希望)有人知道更好:D

所以我在Bluemix上运行了一个Cloudant数据库,我很陌生。 查询,索引,视图 ...在这里苦苦挣扎,但到目前为止,我可以成功检索文档 - 在我的案例中由timestamp过滤。现在我只想让输出更加方便。

在我的数据库中,我的文档结构如下:

{
  "_id": "0048160a463a73faaa6c90f5af027772",
  "_rev": "1-ff6255309f1b873a4e482310843a8a15",
  "timestamp": 1496275536932.6602,
  "results": {
    "lines": {
      "S1": [
        {
          "needed_key": "foo",
          "not_needed_key": 1
        }
      ],
      "S2": [
        {
          "needed_key": "bar",
          "not_needed_key": 1
        },
        {
          "needed_key": "foo_bar",
          "not_needed_key": 1
        }
      ],
      ...
    }
  },
  "station": "5002270",
  "another_not_needed_key": "something"
}

缩短,我的Cloudant选择器看起来有点像这样:

{
  "selector": {
    "$and": [{
      "timestamp": {
        "$gte": from,
        "$lt": to
      },       
      "results.lines": {
        "$ne": {}
      }
    ]},
  "fields": [
    "_id",
    "timestamp",
    "station",
    "results"
  ],
  ...
}

了解"another_not_needed_key"fields的位置,因为我不需要这些信息。现在我想对lines数组的对象中不需要的字段做同样的事情。

我在某处读过,对于数组来说,像是

"results.lines.S1.[].needed_key"

作为selector是可能的,虽然我甚至不确定我是否有任何测试结果。无论如何:

问题:

  1. 上述fields的上述工作是否也应如此?即它应该只输出"needed_key"数组嵌套对象中的任何"S1"吗?尚未取得成功。
  2. 我能以某种方式概括"S1"吗?与数组中所有对象的[]一样,我想要解决lines中的所有键。因为:有些可能包含"S1"作为关键,有些则不包含。总的来说,这里有七个可能的键,可变组合。
  3. 如果有任何不清楚的地方,我很乐意提供更多信息。提前谢谢!

1 个答案:

答案 0 :(得分:1)

  1. 否:(使用带有文本类型索引的[]简写将在您查询时输出数组的全部内容。

  2. 不在Cloudant查询中,没有:(您可以做的最好的事情可能是将数据结构更改为嵌套数组的位置,但这对过滤预测值没有帮助。

  3. 您的查询非常复杂,可能需要创建程序化搜索索引(即,在设计文档中,而不是通过Cloudant查询):https://console.ng.bluemix.net/docs/services/Cloudant/api/search.html#search(如果这听起来很混乱,下面有更多上下文)。

  4. 在较高级别,它取决于您通过Cloudant Query索引数据的方式。有两种方法:"type": "json""type": "text"。 text-type可以使用[]表示法,而json-type则不能。我将解释当前的json类型方法,并将使用文本类型信息进行更新。这也是一个很好的主题:Cloudant/Mango selector for deeply nested JSONs

    要备份一下:在Cloudant中,你不能真正做任何临时查询,你几乎已经知道了,因为你已经走了这么远。在Cloudant / CouchDB中,必须先存在索引才能查询任何内容。 (默认情况下,您将获得"_id"上的主索引。)此外,还有多个索引引擎:1。传统的基于Map的视图,用于创建二级索引,2。Lucene搜索索引,以及3.地理空间索引。 / p>

    Cloudant Query抽象了一些此索引随后查询系统,但您仍然需要告诉它什么&如何索引。它可以创建两种类型的索引:“json”(对应于上面的#1)和“text”(上面的#2)。

    根据您正在观察的行为,看起来您在Cloudant查询中创建了一个json类型的索引,并且正在针对该行为发出选择器语句。这是您用这种方法最接近的地方:

    json-type index:

    {
      "index": {
        "fields": [
          "_id",
          "timestamp",
          "station",
          "results"
        ]
      },
      "type": "json"
    }
    

    json-type选择器

    {
      "selector": {
        "_id": {
          "$gt": 0
        }
      },
      "fields": [
        "_id",
        "timestamp",
        "station",
        "results.lines.S1.0.needed_key",
        "results.lines.S2.0.needed_key",
        "results.lines.S2.1.needed_key"
      ],
      "sort": [
        {
          "_id": "asc"
        }
      ]
    }
    

    <强>输出:

    {
     "_id": "fd298368a7a344b217698677f3f5a07d",
     "timestamp": 1496275536932.6602,
     "station": "5002270",
     "results": {
      "lines": {
       "S1": {
        "0": {
         "needed_key": "foo"
        }
       },
       "S2": {
        "0": {
         "needed_key": "bar"
        },
        "1": {
         "needed_key": "foo_bar"
        }
       }
      }
     }
    }
    

    不幸的是,json类型的方法要求你知道嵌套的方式。

    文本类型的CQ方法不能满足您当前的需求,但这是我认为最接近的方法:

    文字类型索引

    {
      "index": {
        "fields": [
          {"name": "_id", "type": "string"},
          {"name": "timestamp", "type": "number"},
          {"name": "station", "type": "string"},
          {"name":"results.lines.S1.[].needed_key", "type": "string"}
        ]
      },
      "type": "text"
    }
    

    文字类型选择器(已更新以显示更有趣的查询)

    {
      "selector": {
        "results.lines.S1": {
          "$elemMatch": {"needed_key": "foo"}
        }
      },
      "fields": [
        "_id",
        "timestamp",
        "station",
        "results.lines.S1"
      ]
    }
    

    <强>输出

    {
     "_id": "fd298368a7a344b217698677f3f5a07d",
     "timestamp": 1496275536932.6602,
     "station": "5002270",
     "results": {
      "lines": {
       "S1": [
        {
         "needed_key": "foo",
         "not_needed_key": 1
        }
       ]
      }
     }
    }
    

    希望有所帮助。