find(
函數用於搜尋集合中的文件,類似於 SQL 資料庫的 SELECT 陳述式。它採用搜尋條件字串 (SearchConditionStr) 作為參數,以指定應從資料庫傳回的文件。SearchConditionStr
)execute()
函數會觸發 find()
操作的實際執行。
SearchConditionStr 可以是以下其中一種形式
-
如果未指定 SearchConditionStr,
find()
操作會傳回集合中的所有文件。// Get a collection var myColl = session.getSchema("world_x").getCollection("countryinfo"); // To return all documents in world_x: myColl.find().execute();
-
SearchConditionStr 最常見的形式為
JSON-path [ operator { value | JSON-path} ]
以下是一些針對 SearchConditionStr 不同部分的說明
-
JSON-path
:JSON 路徑識別 JSON 文件中的元素;如需詳細資訊,請參閱 JSON 路徑語法。以下是 JSON 路徑語法的簡短摘要-
JSON 路徑以範圍開始:在 MySQL 的 JSON 文件實作中,路徑的範圍一律為正在操作的文件,以
$
表示,此範圍一律隱含假設,因此在大多數情況下可以省略;例如,路徑$.geography.Region
等同於geography.Region
。注意在某些情況下,無法省略
$
;例如當使用
**
萬用字元時 (例如,find("$**.b1")
;請參閱以下有關萬用字元的討論),如果 JSON 路徑僅包含文字字串 (若省略
$
),則為 (例如,find("$.'country_name'")
用於尋找具有country name
欄位的所有文件)。
在範圍之後,路徑由一個或多個路徑段組成。路徑段從 JSON 樹狀結構的一層導向下一層,連續的路徑以句點 (
.
) 分隔。例如:myColl.find("geography.Continent = 'Africa'")
尋找所有在geography
欄位下具有值Africa
的Continent
欄位的文件。-
陣列中的元素以
[
表示,其中N
]N
是陣列索引,且必須是非負整數。myColl.add({ name:'John', favorNums: [1, 3, 5, 7, 9] }).execute(); myColl.find("favorNums[0] = 1").execute(); //Returns the document just added }
-
-
萬用字元符號
*
和**
可在 JSON 路徑中使用,如下所示
代表成員object
.*object
下所有成員的值。例如,在範例world_x
綱要的countryinfo
集合中,geography.*
代表物件geography
下的所有成員,而myColl.find("'Africa' in geography.*")
會傳回在geography
下的任何成員中具有值Africa
的所有文件。-
代表陣列中所有元素的值。例如array
[*]myColl.add({ name:'John', favorNums: [1, 3, 5, 7, 9] }).execute(); myColl.add({ name:'Jane', favorNums: [2, 4, 6, 8, 10] }).execute(); myColl.find("1 in favorNums[*]").execute(); //Returns the first document added above myColl.find("2 in favorNums[*]").execute(); //Returns the second document added above }
-
[
代表文件prefix
]**suffix
prefix
下所有以suffix
結尾的路徑,不論路徑的深度為何。以下範例說明如何使用 ** 傳回不同的結果mysql-js> myColl.find().execute(); { "a": "bar", "b": { "b1": 6, "b2": 7, "b3": { "b1": 99, "b2": 98, "b3": { "b1": 999, "b2": 998 } } }, "_id": "000061313aa10000000000000001" } { "a": "baz", "b": { "b1": 1, "b2": 7 }, "_id": "000061313aa10000000000000002" } { "a": "bbr", "c": 37, "_id": "0000613247ed0000000000000001" } 3 documents in set (0.0007 sec) mysql-js> myColl.find("$**.b2").execute(); { "a": "bar", "b": { "b1": 6, "b2": 7, "b3": { "b1": 99, "b2": 98, "b3": { "b1": 999, "b2": 998 } } }, "_id": "000061313aa10000000000000001" } { "a": "baz", "b": { "b1": 1, "b2": 7 }, "_id": "000061313aa10000000000000002" } 2 documents in set, 1 warning (0.0008 sec) ... mysql-js> myColl.find("$**.b3**.b2").execute(); { "a": "bar", "b": { "b1": 6, "b2": 7, "b3": { "b1": 99, "b2": 98, "b3": { "b1": 999, "b2": 998 } } }, "_id": "000061313aa10000000000000001" } 1 document in set, 1 warning (0.0011 sec) ...
使用
**
萬用字元時,適用以下要求prefix
應為$
或本身為文件的元素。suffix
應為路徑段,且一律為必要 (亦即,路徑表達式不得以**
結尾)。路徑表達式不得包含序列
***
。
-
value
是要與JSON-path
上的元素比較的數值。萬用字元%
和_
可搭配LIKE
運算子在value
中使用,就像在 MySQLWHERE
子句中一樣。例如myColl.find("Name LIKE 'Austra%'") myColl.find("geography.Continent LIKE 'Asi_'")
-
operator
:以下運算子可用於 SearchConditionStr:OR (||)
、AND (&&)
、XOR
、IS
、NOT
、BETWEEN
、IN
、LIKE
、OVERLAPS
、!=
、<>
、>
、>=
、<
、<=
、&
、|
、<<
、>>
、+
、-
、*
、/
、~
和%
。以下是一些使用運算子的範例myColl.find("Name = 'Australia'") myColl.find("demographics.Population >= 1000000" ) myColl.find("demographics.LifeExpectancy BETWEEN 50 AND 60") myColl.find("government.HeadOfState = 'Elizabeth II' AND geography.Region = 'Caribbean'")
如果未提供運算子和後續 JSON 路徑,
find()
會傳回 JSON 路徑所指向的某些非空元素的所有文件。例如myColl.find("demographics.Population" ).execute();
傳回具有
demographics.Population
元素的所有文件{ "GNP": 828, "_id": "00005de917d80000000000000000", "Code": "ABW", "Name": "Aruba", "IndepYear": null, "geography": { "Region": "Caribbean", "Continent": "North America", "SurfaceArea": 193 }, "government": { "HeadOfState": "Beatrix", "GovernmentForm": "Nonmetropolitan Territory of The Netherlands" }, "demographics": { "Population": 103000, "LifeExpectancy": 78.4000015258789 } } { "GNP": 5976, "_id": "00005de917d80000000000000001", ... 232 documents in set, 1 warning (0.0013 sec) Warning (code 3986): Evaluating a JSON value in SQL boolean context does an implicit comparison against JSON integer 0; if this is not what you want, consider converting JSON to an SQL numeric type with JSON_VALUE RETURNING
在 SearchConditionStr 中使用
IN
運算子,以檢查萬用字元涵蓋的所有成員內的值mysql-js> myColl.find("$**.b1").execute(); { "a": "bar", "b": { "b1": 6, "b2": 7, "b3": { "b1": 99, "b2": 98, "b3": { "b1": 999, "b2": 998 } } }, "_id": "000061313aa10000000000000001" } { "a": "baz", "b": { "b1": 1, "b2": 7 }, "_id": "000061313aa10000000000000002" } 2 documents in set, 1 warning (0.0012 sec) ... mysql-js> myColl.find("99 IN $**.b1").execute(); { "a": "bar", "b": { "b1": 6, "b2": 7, "b3": { "b1": 99, "b2": 98, "b3": { "b1": 999, "b2": 998 } } }, "_id": "000061313aa10000000000000001" } 1 document in set (0.0016 sec) ...
OVERLAPS
運算子會比較兩個 JSON 片段,如果兩個片段在任何鍵值組或陣列元素中具有任何共通的值,則傳回 true (1)。例如mysql-js> myColl.find("list").execute(); { "_id": "1", "list": [ 1, 4 ] } { "_id": "2", "list": [ 4, 7 ] } 2 documents in set, 1 warning (0.0010 sec) mysql-js> myColl.find("[1,2,3] OVERLAPS $.list") { "_id": "1", "list": [ 1, 4 ] } 1 document in set (0.0006 sec)
-
數種方法 (例如 fields()
、sort()
和 limit()
) 可以鏈結至 find()
函數,以進一步精簡結果。例如
myColl.find("Name LIKE 'Austra%'").fields("Code")
myColl.find("geography.Continent LIKE 'A%'").limit(10)
也支援使用 bind()
進行參數繫結。以下範例說明如何搭配 find()
使用 bind()
MySQL Shell JavaScript 程式碼
// Use the collection 'my_collection'
var myColl = db.getCollection('my_collection');
// Find a single document that has a field 'name' that starts with 'L'
var docs = myColl.find('name like :param').
limit(1).bind('param', 'L%').execute();
print(docs.fetchOne());
// Get all documents with a field 'name' that starts with 'L'
docs = myColl.find('name like :param').
bind('param','L%').execute();
var myDoc;
while (myDoc = docs.fetchOne()) {
print(myDoc);
}
MySQL Shell Python 程式碼
# Use the collection 'my_collection'
myColl = db.get_collection('my_collection')
# Find a single document that has a field 'name' that starts with 'L'
docs = myColl.find('name like :param').limit(1).bind('param', 'L%').execute()
print(docs.fetch_one())
# Get all documents with a field 'name' that starts with 'L'
docs = myColl.find('name like :param').bind('param','L%').execute()
myDoc = docs.fetch_one()
while myDoc:
print(myDoc)
myDoc = docs.fetch_one()
Node.js JavaScript 程式碼
// Use the collection 'my_collection'
var myColl = db.getCollection('my_collection');
// Find a single document that has a field 'name' that starts with 'L'
myColl
.find('name like :name')
.bind('name', 'L%')
.limit(1)
.execute(function (doc) {
console.log(doc);
})
.then(function () {
// handle details
});
// Get all documents with a field 'name' that starts with 'L'
myColl
.find('name like :name')
.bind('name', 'L%')
.execute(function (doc) {
console.log(doc);
})
.then(function () {
// handle details
});
C# 程式碼
// Use the collection "my_collection"
var myColl = db.GetCollection("my_collection");
// Find a single document that has a field "name" that starts with "L"
var docs = myColl.Find("name like :param")
.Limit(1).Bind("param", "L%").Execute();
Console.WriteLine(docs.FetchOne());
// Get all documents with a field "name" that starts with "L"
docs = myColl.Find("name like :param")
.Bind("param", "L%").Execute();
while (docs.Next())
{
Console.WriteLine(docs.Current);
}
Python 程式碼
# Use the collection 'my_collection'
my_coll = my_schema.get_collection('my_collection')
# Find a single document that has a field 'name' that starts with 'L'
docs = my_coll.find('name like :param').limit(1).bind('param', 'L%').execute()
print(docs.fetch_one())
# Get all documents with a field 'name' that starts with 'L'
docs = my_coll.find('name like :param').bind('param', 'L%').execute()
doc = docs.fetch_one()
print(doc)
Java 程式碼
// Use the collection 'my_collection'
Collection myColl = db.getCollection("my_collection");
// Find a single document that has a field 'name' that starts with 'L'
DocResult docs = myColl.find("name like :name").bind("name", "L%").execute();
System.out.println(docs.fetchOne());
// Get all documents with a field 'name' that starts with 'L'
docs = myColl.find("name like :name").bind("name", "L%").execute();
while (docs.hasNext()) {
DbDoc myDoc = docs.next();
System.out.println(myDoc);
}
C++ 程式碼
// Use the collection 'my_collection'
Collection myColl = db.getCollection("my_collection");
// Find a single document that has a field 'name' that starts with 'L'
DocResult docs = myColl.find("name like :param")
.limit(1).bind("param", "L%").execute();
cout << docs.fetchOne() << endl;
// Get all documents with a field 'name' that starts with 'L'
docs = myColl.find("name like :param")
.bind("param","L%").execute();
DbDoc myDoc;
while ((myDoc = docs.fetchOne()))
{
cout << myDoc << endl;
}
另請參閱 CollectionFindFunction,以取得 EBNF 中 find()
的語法。