我无法诊断我的Java应用程序对MongoDB的请求没有路由到最近的副本的问题,我希望有人可以提供帮助.首先让我解释一下我的配置.
配置:
我正在生产一个Sharded ReplicaSet的MongoDB实例.它目前只是一个单一的碎片(它还没有足够大,还需要拆分).此单个分片由3节点副本集支持.副本集的2个节点位于我们的主数据中心.第三个节点位于我们的辅助数据中心,并且被禁止成为主节点.
我们在两个数据中心同时运行我们的生产应用程序,但是我们的辅助数据中心中的实例以"只读"模式运行,并且从不将数据写入MongoDB.它仅为客户端请求读取现有数据提供服务.此配置的目的是确保如果我们的主数据中心出现故障,我们仍然可以为客户端读取流量提供服务.
我们不希望在我们的辅助数据中心中浪费所有这些硬件,因此即使在愉快的时候,我们也会主动将一部分只读流量负载平衡到在辅助数据中心运行的应用程序实例.此应用程序实例配置为readPreference = NEAREST,并指向在localhost(版本2.6.7)上运行的mongos实例.mongos实例显然配置为指向我们的3节点副本集.
来自mongos:
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"version" : 4,
"minCompatibleVersion" : 4,
"currentVersion" : 5,
"clusterId" : ObjectId("52a8932af72e9bf3caad17b5")
}
shards:
{ "_id" : "shard1", "host" : "shard1/failover1.com:27028,primary1.com:27028,primary2.com:27028" }
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "test", "partitioned" : false, "primary" : "shard1" }
{ "_id" : "MyApplicationData", "partitioned" : false, "primary" : "shard1" }
Run Code Online (Sandbox Code Playgroud)
从replicaset的故障转移节点:
shard1:SECONDARY> rs.status() …Run Code Online (Sandbox Code Playgroud) 我的文档中有以下结构:
{
_id : ObjectId("43jh4j343j4j"),
array : [
{
_arrayId : ObjectId("dsd87dsa9d87s9d7"),
someField : "something",
someField2 : "something2"
},
{
_arrayId : ObjectId("sds9a0d9da0d9sa0"),
someField : "somethingElse",
someField2 : "somethingElse2"
}
]
}
Run Code Online (Sandbox Code Playgroud)
我想更新someField和someField2但仅针对数组中的一个项目,匹配_arrayId的项目(例如_arrayId : ObjectId("dsd87dsa9d87s9d7");仅用于此文档(例如_id : ObjectId("43jh4j343j4j"))而不是其他项目).
该arrayIds是不是唯一的,这就是为什么我需要它是针对特定文档的文档.我可以使用$ positional operatorif if我想在数组中为它存在的每个文件更新该值,但这不是我想要的.
我试图在java中实现这一点,但命令行解决方案也可以.
我正在亚马逊ec2上运行java进程.它跑了72分钟,然后我突然得到"java结果137".就是这样,没有例外或任何其他错误消息.我搜索了这个错误,但找不到任何有用的东西.可能是什么原因以及如何解决?请告诉我.
使用mongodb java驱动程序的第3版(特别是v3.0.1)来复制文档的惯用方法是什么?
我们有一个会话集合,当一个新会话被创建或修改时,我们想要在一个操作中插入它 - 而不是必须查询文档是否存在然后插入或替换.
我们的旧upsertion代码使用了scala驱动程序casbah 2.7.3.它看起来像:
import com.mongodb.casbah.MongoCollection
import com.mongdb.DBObject
val sessionCollection: MongoCollection = ...
val sessionKey: String = ...
val sessionDocument: DBObject = ... // Either create a new one, or find and modify an existing one
sessionCollection.update(
"_id" -> sessionKey,
sessionDocument
upsert = true
)
Run Code Online (Sandbox Code Playgroud)
在我们当前的项目中,我们只是使用普通的java 3.0.1驱动程序,我们正在使用BsonDocument而不是DBObject使它更具典型性.我尝试用以下内容替换上面的内容:
import com.mongodb.client.MongoCollection
val sessionCollection: MongoCollection = ...
val sessionKey: String = ...
val sessionDocument: BsonDocument = // Either create a new one, or find and modify …Run Code Online (Sandbox Code Playgroud) 我有一个Java应用程序在MongoDB上执行一些聚合,但有时它只是挂起并抛出一个SocketTimeout异常.在异常之后,应用程序将运行正常(稍微,然后它可能会再次引发异常).
我刚刚发现这个解释似乎是可能的原因,但我不确定.
我初始化MongoClient并保持与DB的连接打开.我不确定这是否是一个问题,我应该每次都得到数据库,然后让数据库被垃圾收集(并关闭连接).
另一种方法可能是定期ping Mongo以保持连接池"新鲜".
使用的客户端是这样的:
public class DbClient {
private static MongoClient mongoClient;
private static MongoDatabase db;
private DbClient() {}
public static void init() throws Exception {
mongoClient = new MongoClient();
}
public static MongoDatabase getDB() {
if(mongoClient == null)
throw new IllegalStateException("Client not initialized!");
if(db == null) {
db = mongoClient.getDatabase("my_db");
}
return db;
}
}
Run Code Online (Sandbox Code Playgroud)
这是SocketTimeout的可能原因吗?
这是抛出的异常:
09:20:45.742 [qtp605535417-46] INFO org.mongodb.driver.connection - Closed connection [connectionId{localValue:16, serverValue:6562}] to myapp.com:27017 because there was a socket exception raised …Run Code Online (Sandbox Code Playgroud) 我有一个具有以下结构的mongodb集合term
{
"_id" : "00002c34-a4ca-42ee-b242-e9bab8e3a01f",
"terminologyClass" : "USER",
"code" : "X67",
"terminology" : "some term related notes",
"notes" : "some notes"
}
Run Code Online (Sandbox Code Playgroud)
和一个表示术语集合的java类 Term.java
@Document
public class Term{
@Id
protected String termId;
@Indexed
protected String terminologyClass;
@Indexed(unique=true)
protected String code;
@Indexed
protected String terminology;
protected String notes;
//getters & setters
}
Run Code Online (Sandbox Code Playgroud)
我term收藏了很多文件.现在我添加了一个新字段Term.javaas
@Indexed
protected String status;
Run Code Online (Sandbox Code Playgroud)
添加字段status后Term.java,在向term集合中插入新术语时,我得到了一个例外:
com.mongodb.MongoException:带名称的索引:代码已经存在,具有不同的选项
我使用的是MongoDB版本:2.6.5和spring-data-mongodb版本:1.3.2
我有一个文档
{_id:NumberLong(1),gender:"M",vip:false}.
Run Code Online (Sandbox Code Playgroud)
如何使用查询在 Mongo 中提取单个字段的类型.. 如何使用 typeof 运算符:
我最近安装了Java MongoDB Driver 3.1.1版本,我想知道findOneAndUpdate和之间的区别是什么findOneAndReplace?
在什么情况下我应该使用每一个?
有没有简单的方法将Simple POJO转换为org.bson.Document?
我知道有很多方法可以像这样做:
Document doc = new Document();
doc.append("name", person.getName()):
Run Code Online (Sandbox Code Playgroud)
但它有一个更简单和更错误的方式吗?