建立選取元表示式
一般而言,只要您有一個採用引數的運算子,該引數本身就可以是另一個具有其本身引數的運算子。 此擴充會啟用更複雜的選取元表示式。
當您使用 JSON 類型的索引時,組合或陣列邏輯運算子 (例如 $regex
) 可能會導致完整資料庫掃描,導致效能不佳。 僅限相等運算子,例如 $eq
,
$gt
、$gte
、$lt
及 $lte
(但不是 $ne
),啟用索引查閱。 若要確保有效使用索引,請分析 每一個查詢的 解譯計劃。
大部分選取元表示式的運作方式與您預期的運算子完全相同。
$regex
運算子所使用的比對演算法目前 基於 Perl Compatible Regular Expression(PCRE)程式庫。 不過,並非所有 PCRE 程式庫都已實作。 此外,
$regex
運算子的部分部分已超出 PCRE 提供的範圍。 如需實作內容的相關資訊,請參閱 Erlang 正規表示式 資訊。
排序語法
sort
欄位包含欄位名稱及方向配對的清單,以基本陣列表示。 第一個欄位名稱及方向配對是排序的最上層。 進一步的配對 (如果提供的話) 會指定下一個排序層次。
排序欄位可以是任何欄位。 必要的話,請對子欄位使用帶點表示法。
方向值為 asc
(升冪),desc
(降冪)。
如果您排除方向值,則會使用預設 asc
。
請參閱下列簡式排序語法範例:
[
{
"fieldName1": "desc"
},
{
"fieldName2": "desc"
}
]
請參閱下列簡式排序範例,並假設兩個欄位的預設方向都是 "ascending":
[
"fieldNameA", "fieldNameB"
]
一般需求是使用選取器來搜尋部分內容,然後根據指定的欄位,以偏好的方向來排序結果。
若要使用排序,必須定義包含排序欄位的索引。 如果使用 json
索引,則必須以與排序相同的順序指定欄位。
目前,IBM Cloudant 查詢不支援多個具有不同排序順序的欄位,因此方向必須全部遞增或全部遞減。
如果方向是遞增,您可以使用字串而非物件來指定排序欄位。
對於排序查詢中針對 text
索引的欄位名稱,如果無法判定要排序的欄位類型,則可能需要指定欄位類型。 例如:
{
"<fieldname>:string": "asc"
}
查詢使用哪個索引? | 欄位類型需求 |
---|---|
JSON 索引 | 無 |
所有文件中所有欄位的文字索引 | 如果資料庫包含排序欄位具有一種類型的文件,請在查詢中指定排序欄位。 此外,如果查詢包含排序欄位具有不同類型的文件,請在查詢中指定排序欄位。 |
任何其他文字索引 | 指定查詢中所有排序欄位的類型。 |
當您使用語法時,會建立所有文件中所有欄位的文字索引:
"index": {}
.
當欄位包含不同的資料類型時,未定義排序順序。 此性質是文字與視圖索引之間的重要差異。 在未來版本中,具有不同資料類型之欄位的排序行為可能會變更。
請參閱下列使用排序的簡式查詢範例:
{
"selector": {
"Actor_name": "Robert De Niro"
},
"sort": [
{
"Actor_name": "asc"
},
{
"Movie_runtime": "asc"
}
]
}
過濾欄位
當您從資料庫中選取時,可以確切指定針對文件傳回的欄位。 這兩個優點顯示在下列清單中:
- 您的結果僅限於應用程式所需的文件部分。
- 減少回應的大小。
要傳回的欄位指定為陣列。
回應中只包含指定的過濾器欄位。_id
或其他 meta 資料欄位不會自動併入。
請參閱下列從相符文件選擇性擷取欄位的範例:
{
"selector": {
"Actor_name": "Robert De Niro"
},
"fields": [
"Actor_name",
"Movie_year",
"_id",
"_rev"
]
}
分頁
IBM Cloudant 查詢支援透過書籤欄位進行分頁。 每個 _find
回應都包含書籤- IBM Cloudant 用來決定在稍後進行查詢時要從何處回復的記號。 若要取得下一組查詢結果,請將前一個回應中收到的書籤新增至下一個要求。 請記得保持選取元相同,否則您會收到非預期的結果。 若要向後分頁,您可以使用前一個書籤來傳回前一個結果集。
書籤的存在並不保證會有更多結果。 您可以比較傳回的結果數目與所要求的頁面大小,來測試您是否在結果集的結尾。 如果傳回的結果小於限制,則結果集中未傳回更多結果。
說明計劃
IBM Cloudant 除非您在查詢時指定索引,否則查詢會選擇用於回應查詢的索引。
當您指定要使用的索引時, IBM Cloudant 查詢使用下列邏輯:
- 查詢規劃程式會查看選取器區段,並尋找與查詢中使用的運算子及欄位最相符的索引。 如果兩個以上 JSON 類型索引相符,則偏好索引中具有最少欄位數的索引。 如果仍有兩個以上候選項索引存在,則會選擇具有第一個字母名稱的索引。
- 如果
json
類型索引 和text
類型索引可能都滿足選取器,依預設會選擇json
索引。 - 當符合下列條件時,會選擇
text
類型索引:json
類型索引 和text
類型索引存在於相同的欄位中 (例如fieldone
)。- 只能使用
text
類型索引來滿足選取元。
例如,假設您具有 text
類型索引和 json
欄位 foo
的類型索引,並且您想要使用類似於下列範例的選取器:
{
"foo": {
"$in": ["red","blue","green"]
}
}
IBM Cloudant 查詢會使用 text
類型索引,因為 json
類型索引無法滿足選取器。
不過,您可以使用具有相同索引的不同選取器:
{
"foo": {
"$gt": 2
}
}
在此範例中, IBM Cloudant 查詢會使用 json
類型索引,因為這兩種類型的索引都可以滿足選取器。
若要識別特定查詢正在使用的索引,請將 POST
傳送至資料庫的 _explain
端點,並以查詢作為資料。 使用中索引的詳細資料會顯示在結果內的 index
物件中。
請參閱下列使用 HTTP 的範例,以顯示如何識別用來回答查詢的索引:
POST /movies/_explain HTTP/1.1
Host: $SERVICE_URL
Content-Type: application/json
{
"selector": {
"$text": "Pacino",
"year": 2010
}
}
請參閱下列使用指令行的範例,以顯示如何識別用來回答查詢的索引:
curl "$SERVICE_URL/movies/_explain" \
-X POST \
-H "Content-Type: application/json" \
-d '{
"selector": {
"$text": "Pacino",
"year": 2010
}
}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.ExplainResult;
import com.ibm.cloud.cloudant.v1.model.PostExplainOptions;
import java.util.HashMap;
import java.util.Map;
Cloudant service = Cloudant.newInstance();
Map<String, Object> selector = new HashMap<>();
selector.put("$text", "Pacino");
selector.put("year", 2010);
PostExplainOptions explainOptions =
new PostExplainOptions.Builder()
.db("movies")
.selector(selector)
.build();
ExplainResult response =
service.postExplain(explainOptions).execute()
.getResult();
System.out.println(response);
import { CloudantV1 } from '@ibm-cloud/cloudant';
const service = CloudantV1.newInstance({});
let selector: CloudantV1.Selector = {
'$text': 'Pacino',
'year': 2010
};
service.postExplain({
db: 'movies',
selector: selector
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.post_find(
db='movies',
selector={'$text': 'Pacino', 'year': 2010}
).get_result()
print(response)
postExplainOptions := service.NewPostExplainOptions(
"movies",
map[string]interface{}{
"$text": "Pacino",
"year": 2010,
},
)
explainResult, _, err := service.PostExplain(postExplainOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(explainResult, "", " ")
fmt.Println(string(b))
前一個 Go 範例需要下列匯入區塊:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
請參閱下列範例回應,其中顯示用來回答查詢的索引:
{
"dbname": "$ACCOUNT/movies",
"index": {
"ddoc": "_design/32372935e14bed00cc6db4fc9efca0f1537d34a8",
"name": "32372935e14bed00cc6db4fc9efca0f1537d34a8",
"type": "text",
"def": {
"default_analyzer": "keyword",
"default_field": {},
"selector": {},
"fields": []
}
},
"selector": {
"$and": [
{
"$default": {
"$text": "Pacino"
}
},
{
"year": {
"$eq": 2010
}
}
]
},
"opts": {
"use_index": [],
"bookmark": [],
"limit": 10000000000,
"skip": 0,
"sort": {},
"fields": "all_fields",
"r": [
49
],
"conflicts": false
},
"limit": 200,
"skip": 0,
"fields": "all_fields",
"query": "(($default:Pacino) AND (year_3anumber:2010))",
"sort": "relevance"
}
若要指示查詢使用特定索引,請將 use_index
參數新增至查詢。
use_index
參數的值採用下列其中一種格式:
"use_index": "$DDOC"
"use_index": ["$DDOC","$INDEX_NAME"]
請參閱下列範例查詢,並提供使用特定索引的指示:
{
"selector": {
"$text": "Pacino",
"year": 2010
},
"use_index": "_design/32372935e14bed00cc6db4fc9efca0f1537d34a8"
}