发布于 2015-09-14 14:41:28 | 230 次阅读 | 评论: 0 | 来源: 网络整理
MongoDB 2.4 is currently in development, as part of the 2.3 development release series. While 2.3-series releases are currently available, these versions of MongoDB are for testing only, and are not for production use under any circumstances.
重要
All interfaces and functionality described in this document are subject to change before the 2.4.0 release.
This document will eventually contain the full release notes for MongoDB 2.4; during the development cycle this document will contain documentation of new features and functionality only available in the 2.3 releases.
See the full index of this page for a complete list of changes included in 2.4.
You can download the 2.3 release on the downloads page in the Development Release (Unstable) section. There are no distribution packages for development releases, but you can use the binaries provided for testing purposes. See 在Linux上安装, 在Windows上安装, or 在OS X上安装 for the basic installation process.
See 更新 MongoDB 2.2 到 2.4 for full upgrade instructions.
注解
The text index type is currently an experimental feature. To use a text index, you need to enable it at run time or startup.
MongoDB 2.3.2 includes a new text index type. text indexes support boolean text search queries:
However, text indexes have large storage requirements and incur significant performance costs:
Additionally, the current experimental implementation of text indexes have the following limitations and behaviors:
警告
Do not enable or use text indexes on production systems.
The text index type is an experimental feature and you need to enable the feature before creating or accessing a text index.
To enable text indexes, issue the following command in the mongo shell:
警告
Do not enable or use text indexes on production systems.
db.adminCommand( { setParameter: 1, textSearchEnabled: true } )
You can also start the mongod with the following invocation:
mongod --setParameter textSearchEnabled=true
To create a text index, use the following syntax of ensureIndex():
db.collection.ensureIndex( { <field>: "text" } )
Consider the following example:
db.collection.ensureIndex( { content: "text" } )
This text index catalogs all string data in the content field where the content field contains a string or an array of string elements. To index fields in sub-documents, you need to specify the individual fields from the sub-documents using the dot notation. A text index can include multiple fields, as in the following:
db.collection.ensureIndex( { content: "text",
"users.comments": "text",
"users.profiles": "text" } )
The default name for the index consists of the <field name> concatenated with _text for the indexed fields, as in the following:
"content_text_users.comments_text_users.profiles_text"
These indexes may run into the Index Name Length limit. To avoid creating an index with a too-long name, you can specify a name in the options parameter, as in the following:
db.collection.ensureIndex( { content: "text",
"users.profiles": "text" },
{ name: "TextIndex" } )
When creating text indexes you may specify weights for specific fields. Weights are factored into the relevant score for each document. The score for a given word in a document is the weighted sum of the frequency for each of the indexed fields in that document. Consider the following:
db.collection.ensureIndex( { content: "text",
"users.profiles": "text" },
{ name: "TextIndex",
weights: { content: 1,
"users.profiles": 2 } } )
This example creates a text index on the top-level field named content and the profiles field in the users sub-documents. Furthermore, the content field has a weight of 1 and the users.profiles field has a weight of 2.
You can add a conventional ascending or descending index field(s) as a prefix or suffix of the index. You cannot include multi-key index field nor geospatial index field.
If you create an ascending or descending index as a prefix of a text index:
Create this index with the following operation:
db.collection.ensureIndex( { username: 1,
"users.profiles": "text" } )
Alternatively you create an ascending or descending index as a suffix to a text index. Then the text index can support covered queries if the text command specifies a project option.
Create this index with the following operation:
db.collection.ensureIndex( { "users.profiles": "text",
username: 1 } )
Finally, you may use the special wild card field specifier (i.e. $**) to specify index weights and fields. Consider the following example that indexes any string value in the data of every field of every document in a collection and names it TextIndex:
db.collection.ensureIndex( { "$**": "text",
username: 1 },
{ name: "TextIndex" } )
By default, an index field has a weight of 1. You may specify weights for a text index with compound fields, as in the following:
db.collection.ensureIndex( { content: "text",
"users.profiles": "text",
comments: "text",
keywords: "text",
about: "text" },
{ name: "TextIndex",
weights:
{ content: 10,
"user.profiles": 2,
keywords: 5,
about: 5 } } )
This index, named TextIndex, includes a number of fields, with the following weights:
This means that documents that match words in the content field will appear in the result set more than all other fields in the index, and that the user.profiles and comments fields will be less likely to appear in responses than words from other fields.
注解
You must drop a text index using the name specified when you created the index. Alternatively, if you did not specify a name when creating the index, you can find the name using db.collection.getIndexes()
The default language associated with the indexed data determines the list of stop words and the rules for the stemmer and tokenizer. The default language for the indexed data is english.
Use the default_language option when creating the text index to specify a different language. See Languages Supported in Text Search.
The following example creates a text index on the content field and sets the default_language to spanish:
db.collection.ensureIndex( { content : "text" },
{ default_language: "spanish" } )
If a collection contains documents that are in different languages, the individual documents can specify the language to use.
By default, if the documents in the collection contain a field named language, the value of the language field overrides the default language.
For example, the following document overrides the default language spanish with portuguese, the value in its language field.
{ content: "A sorte protege os audazes", language: "portuguese" }
To use a different field to override the default language, specify the field with the language_override option when creating the index.
For example, if the documents contain the field named myLanguage instead of language, create the text index with the language_override option.
db.collection.ensureIndex( { content : "text" },
{ language_override: "myLanguage" } )
MongoDB 2.3.2 introduces the text command to provide query support for text indexes. Unlike normal MongoDB queries, text returns a document rather than a cursor.
The text provides an interface to search text context stored in the text index. Consider the following prototype: text:
db.collection.runCommand( "text", { search: <string>,
filter: <document>,
project: <document>,
limit: <number>,
language: <string> } )
The text command has the following parameters:
参数: |
|
---|---|
返回: | text returns results, in descending order by score, in the form of a document. Results must fit within the BSON Document Size. Use the limit and the project parameters to limit the size of the result set. |
The implicit connector between the terms of a multi-term search is a disjunction (OR). Search for "first second" searches for "first" or "second". The scoring system will prefer documents that contain all terms.
However, consider the following behaviors of text queries:
Example
Consider the following examples of text queries. All examples assume that you have a text index on the field named content in a collection named collection.
Create a text index on the content field to enable text search on the field:
db.collection.ensureIndex( { content: "text" } )
Search for a single word coffee:
db.collection.runCommand( "text", { search: "coffee" } )
This query returns documents that contain the word coffee, case-insensitive, in the content field.
Search for multiple words, bake or coffee or cake:
db.collection.runCommand( "text", { search: "bake coffee cake" } )
This query returns documents that contain the either bake or coffee or cake in the content field.
Search for the exact phrase bake coffee cake:
db.collection.runCommand( "text", { search: ""bake coffee cake"" } )
This query returns documents that contain the exact phrase bake coffee cake.
Search for documents that contain the words bake or coffee, but not cake:
db.collection.runCommand( "text", { search: "bake coffee -cake" } )
Use the - as a prefix to terms to specify negation in the search string. The query returns documents that contain the either bake or coffee, but not cake, all case-insensitive, in the content field. Prefixing a word with a hyphen (-) negates a word:
Search for a single word coffee with an additional filter on the about field, but limit the results to 2 documents with the highest score and return only the comments field in the matching documents:
db.collection.runCommand( "text", {
search: "coffee",
filter: { about: /desserts/ },
limit: 2,
project: { comments: 1, _id: 0 }
}
)
注解
These features are only present in the MongoDB Subscriber Edition. To download the 2.4.0 release candidate the Subscriber Edition, use the following resources:
An improved authentication system is a core focus of the entire 2.3 cycle, as of 2.3.2, the following components of the new authentication system are available for use in MongoDB:
Development work on this functionality is ongoing, and additional related functionality is forthcoming. To use Kerberos with MongoDB as of the 2.4.0 release candidate, consider the following requirements:
To start mongod with Kerberos support (i.e. with the GSSAPI authentication mechanism,) you must have a working Kerberos environment and a valid Kerberos keytab file.
To start mongod, use a command in the following form:
env KRB5_KTNAME=<path to keytab file> <mongod invocation>
You must start mongod with auth or keyFile [1] and configuring the list of in the authenticationMechanisms parameter. An actual command would resemble:
env KRB5_KTNAME=/opt/etc/mongodb.keytab
/opt/bin/mongod --dbpath /opt/data/db --logpath /opt/log/mongod.log --fork
--auth --setParameter authenticationMechanisms=GSSAPI
Replace the paths as needed for your test deployment.
If you want to enable both Kerberos and the legacy challenge-and-response authentication mechanism, append MONGO-CR to the authenticationMechanisms parameter. Consider the following example:
env KRB5_KTNAME=/opt/etc/mongodb.keytab
/opt/bin/mongod --dbpath /opt/data/db --logpath /opt/log/mongod.log --fork
--auth --setParameter authenticationMechanisms=GSSAPI,MONGO-CR
注解
If you’re having trouble getting mongod to start with Kerberos, there are a number of Kerberos-specific issues that can prevent successful authentication. As you begin troubleshooting your Kerberos deployment, ensure that:
Until you can successfully authenticate a client using the Kerberos you may want to enable MONGO-CR authentication mechanism to provide access to the mongod instance during configuration.
[1] | keyFile implies auth. You must use keyFile for replica sets. |
To use Kerberos with the mongo shell, begin by initializing a Kerberos session with kinit. Then start a 2.3.2 mongo shell instance, and use the following sequence of operations to associate the current connection with the Kerberos session:
use $external
db.auth( { mechanism: "GSSAPI", user: "<username>@<REALM>" } )
The value of the user field must be the same principal that you initialized with kinit. This connection will acquire access in accordance with all privileges granted to this user for all databases.
The default JavaScript engine used throughout MongoDB, for the mongo shell, mapReduce, $where, group, and eval is now V8.
The interpreterVersion field of the document output by db.serverBuildInfo() in the mongo shell reports which JavaScript interpreter the mongod instance is running.
The interpreterVersion() in the mongo shell reports which JavaScript interpreter this mongo shell uses.
The primary impacts of the switch to V8 are:
Previously, MongoDB operations that required the JavaScript interpreter had to acquire a lock, and a single mongod could only run a single JavaScript operation at a time. The switch to V8 improves concurrency by permiting multiple JavaScript operations to run at the same time.
The 5th edition of ECMAscript, abbreviated as ES5, adds many new language features, including:
With V8, MongoDB supports the latest standardized version of JavaScript with the following exceptions. The following features do not work as expected on documents returned from MongoDB queries:
V8 does not support the following non-standard SpiderMonkey JavaScript extensions, previously supported by MongoDB’s use of SpiderMonkey as its JavaScript engine.
V8 does not support the non-standard E4X extensions. E4X provides a native XML object to the JavaScript language and adds the syntax for embedding literal XML documents in JavaScript code.
You need to use alternative XML processing if you used any of the following constructors/methods:
V8 does not support the non-standard destructuring assignments. Destructuring assignment “extract[s] data from arrays or objects using a syntax that mirrors the construction of array and object literals.” - Mozilla docs
Example
The following destructuring assignment is invalid with V8 and throws a SyntaxError:
original = [4, 8, 15];
var [b, ,c] = a; // <== destructuring assignment
print(b) // 4
print(c) // 15
V8 does not support Iterator(), StopIteration(), and generators.
V8 does not support InternalError(). Use Error() instead.
V8 does not support the use of for each...in construct. Use for (var x in y) construct instead.
Example
The following for each (var x in y) construct is invalid with V8:
var o = { name: 'MongoDB', version: 2.4 };
for each (var value in o) {
print(value);
}
Instead, in version 2.4, you can use the for (var x in y) construct:
var o = { name: 'MongoDB', version: 2.4 };
for (var prop in o) {
var value = o[prop];
print(value);
}
You can also use the array instance method forEach() with the ES5 method Object.keys():
Object.keys(o).forEach(function (key) {
var value = o[key];
print(value);
});
V8 does not support Array comprehensions.
Use other methods such as the Array instance methods map(), filter(), or forEach().
Example
With V8, the following array comprehension is invalid:
var a = { w: 1, x: 2, y: 3, z: 4 }
var arr = [i * i for each (i in a) if (i > 2)]
printjson(arr)
Instead, you can implement using the Array instance method forEach() and the ES5 method Object.keys() :
var a = { w: 1, x: 2, y: 3, z: 4 }
var arr = [];
Object.keys(a).forEach(function (key) {
var val = a[key];
if (val > 2) arr.push(val * val);
})
printjson(arr)
注解
The new logic uses the Array instance method forEach() and not the generic method Array.forEach(); V8 does not support Array generic methods. See Array Generic Methods for more information.
V8 does not support multiple catch blocks and will throw a SyntaxError.
Example
The following multiple catch blocks is invalid with V8 and will throw "SyntaxError: Unexpected token if":
try {
something()
} catch (err if err instanceof SomeError) {
print('some error')
} catch (err) {
print('standard error')
}
V8 will produce different outcomes than SpiderMonkey with conditional function definitions.
Example
The following conditional function definition produces different outcomes in SpiderMonkey versus V8:
function test () {
if (false) {
function go () {};
}
print(typeof go)
}
With SpiderMonkey, the conditional function outputs undefined, whereas with V8, the conditional function outputs function.
If your code defines functions this way, it is highly recommended that you refactor the code. The following example refactors the conditional function definition to work in both SpiderMonkey and V8.
function test () {
var go;
if (false) {
go = function () {}
}
print(typeof go)
}
The refactored code outputs undefined in both SpiderMonkey and V8.
注解
ECMAscript prohibits conditional function definitions. To force V8 to throw an Error, enable strict mode.
function test () {
'use strict';
if (false) {
function go () {}
}
}
The JavaScript code throws the following syntax error:
SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function.
V8 does not support String generics. String generics are a set of methods on the String class that mirror instance methods.
Example
The following use of the generic method String.toLowerCase() is invalid with V8:
var name = 'MongoDB';
var lower = String.toLowerCase(name);
With V8, use the String instance method toLowerCase() available through an instance of the String class instead:
var name = 'MongoDB';
var lower = name.toLowerCase();
print(name + ' becomes ' + lower);
With V8, use the String instance methods instead of following generic methods:
String.charAt() | String.quote() | String.toLocaleLowerCase() |
String.charCodeAt() | String.replace() | String.toLocaleUpperCase() |
String.concat() | String.search() | String.toLowerCase() |
String.endsWith() | String.slice() | String.toUpperCase() |
String.indexOf() | String.split() | String.trim() |
String.lastIndexOf() | String.startsWith() | String.trimLeft() |
String.localeCompare() | String.substr() | String.trimRight() |
String.match() | String.substring() |
V8 does not support Array generic methods. Array generics are a set of methods on the Array class that mirror instance methods.
Example
The following use of the generic method Array.every() is invalid with V8:
var arr = [4, 8, 15, 16, 23, 42];
function isEven (val) {
return 0 === val % 2;
}
var allEven = Array.every(arr, isEven);
print(allEven);
With V8, use the Array instance method every() available through an instance of the Array class instead:
var allEven = arr.every(isEven);
print(allEven);
With V8, use the Array instance methods instead of the following generic methods:
Array.concat() | Array.lastIndexOf() | Array.slice() |
Array.every() | Array.map() | Array.some() |
Array.filter() | Array.pop() | Array.sort() |
Array.forEach() | Array.push() | Array.splice() |
Array.indexOf() | Array.reverse() | Array.unshift() |
Array.join() | Array.shift() |
V8 does not support the Array instance method toSource(). Use the Array instance method toString() instead.
V8 does not support the non-standard method uneval(). Use the standardized JSON.stringify() method instead.
In MongoDB 2.4, map-reduce operations, the group command, and $where operator expressions cannot access certain global functions or properties, such as db, that are available in the mongo shell.
When upgrading to MongoDB 2.4, you will need to refactor your code if your map-reduce operations, group commands, or $where operator expressions include any global shell functions or properties that are no longer available, such as db.
The following shell functions and properties are available to map-reduce operations, the group command, and $where operator expressions in MongoDB 2.4:
Available Properties | Available Functions | |
---|---|---|
args
MaxKey
MinKey
|
assert()
BinData()
DBPointer()
DBRef()
doassert()
emit()
gc()
HexData()
hex_md5()
isNumber()
isObject()
ISODate()
isString()
|
Map()
MD5()
NumberInt()
NumberLong()
ObjectId()
print()
sleep()
Timestamp()
tojson()
tojsononeline()
tojsonObject()
UUID()
version()
|
注解
In 2.3.2, the index type for Spherical Geospatial Indexes become 2dsphere.
The 2.3 series adds a new type of geospatial index that supports improved spherical queries and GeoJSON. Create the index by specifying 2dsphere as the value of the field in the index specification, as any of the following:
db.collection.ensureIndex( { geo: "2dsphere" } )
db.collection.ensureIndex( { type: 1, geo: "2dsphere" } )
db.collection.ensureIndex( { geo: "2dsphere", type: 1 } )
In the first example you create a spherical geospatial index on the field named geo, in the second example, you create a compound index where the first field is a normal index, and the index of the second field is a spherical geospatial index. Unlike 2d indexes, fields indexed using the 2dsphere type do not have to be the first field in a compound index.
You must store data in the fields indexed using the 2dsphere index using the GeoJSON specification, at the moment. Support for storing points, in the form used by the existing 2d (i.e. geospatial) indexes is forthcoming. Currently, 2dsphere indexes only support the following GeoJSON shapes:
Point, as in the following:
{ "type": "Point", "coordinates": [ 40, 5 ] }
LineString, as in the following:
{ "type": "LineString", "coordinates": [ [ 40, 5 ], [ 41, 6 ] ] }
Polygon, as in the following:
{
"type": "Polygon",
"coordinates": [ [ [ 40, 5 ], [ 40, 6 ], [ 41, 6 ], [ 41, 5 ], [ 40, 5 ] ] ]
}
To query 2dsphere indexes, all current geospatial query operators with an additional $geoIntersects operator. Currently, all queries using the 2dsphere index must pass the query selector (e.g. $near, $geoIntersects) a GeoJSON document. With the exception of the GeoJSON requirement, the operation of $near is the same for 2dsphere indexes as 2d indexes.
The $geoIntersects selects all indexed points that intersect with the provided geometry. (i.e. Point, LineString, and Polygon.) You must pass $geoIntersects a document in GeoJSON format.
db.collection.find( { $geoIntersects: { $geometry: { "type": "Point", "coordinates": [ 40, 5 ] } } } )
This query will select all indexed objects that intersect with the Point with the coordinates [ 40, 5 ]. MongoDB will return documents as intersecting if they have a shared edge.
The $geometry operator takes a single GeoJSON document.
If your mongod instance was building an index when it shutdown or terminated, mongod will now continue building the index when the mongod restarts. Previously, the index build had to finish building before mongod shutdown.
To disable this behavior the 2.3 series adds a new run time option, noIndexBuildRetry (or via,q --noIndexBuildRetry on the command line,) for mongod. noIndexBuildRetry prevents mongod from continuing rebuilding indexes that did were not finished building when the mongod last shut down.
To support an easy to configure and evenly distributed shard key, version 2.3 adds a new “hashed” index type that indexes based on hashed values. This section introduces and documents both the new index type and its use in sharding:
The new hashed index exists primarily to support automatically hashed shard keys. Consider the following properties of hashed indexes:
Hashed indexes must only have a single field, and cannot be compound indexes.
Fields indexed with hashed indexes must not hold arrays. Hashed indexes cannot be multikey indexes.
Hashed indexes cannot have a unique constraint.
You may create hashed indexes with the sparse property.
MongoDB can use the hashed index to support equality queries, but cannot use these indexes for range queries.
Hashed indexes offer no performance advantage over normal indexes. However, hashed indexes may be smaller than a normal index when the values of the indexed field are larger than 64 bits. [2]
it’s possible to have a hashed and non-hashed index on the same field: MongoDB will use the non-hashed for range queries.
警告
Hashed indexes round floating point numbers to 64-bit integers before hashing. For example, a hashed index would store the same value for a field that held a value of 2.3 and 2.2. To prevent collisions do not use a hashed index for floating point numbers that cannot be consistently converted to 64-bit integers (and then back to floating point.) Hashed indexes do not support floating point values larger than 253.
Create a hashed index using an operation that resembles the following:
db.records.ensureIndex( { a: "hashed" } )
This operation creates a hashed index for the records collection on the a field.
[2] | The hash stored in the hashed index is 64 bits long. |
To shard a collection using a hashed shard key, issue an operation in the mongo shell that resembles the following:
sh.shardCollection( "records.active", { a: "hashed" } )
This operation shards the active collection in the records database, using a hash of the a field as the shard key. Consider the following properties when using a hashed shard key:
As with other kinds of shard key indexes, if your collection has data, you must create the hashed index before sharding. If your collection does not have data, sharding the collection will create the appropriate index.
The mongos will route all equality queries to a specific shard or set of shards; however, the mongos must route range queries to all shards.
When using a hashed shard key on a new collection, MongoDB automatically pre-splits the range of 64-bit hash values into chunks. By default, the initial number of chunks is equal to twice the number of shards at creation time. You can change the number of chunks created, using the numInitialChunks option, as in the following invocation of shardCollection:
db.adminCommand( { shardCollection: "test.collection",
key: { a: "hashed"},
numInitialChunks: 2001 } )
MongoDB will only pre-split chunks in a collection when sharding empty collections. MongoDB will not create chunk splits in a collection sharding collections that have data.
警告
Avoid using hashed shard keys when the hashed field has non-integral floating point values, see hashed indexes for more information.