我正在编写一个应用程序,将来自第三方数据源的实体同步到我们自己的架构中,其间有转换/映射步骤.我正在使用Hibernate来表示和持久化我们自己的架构中的实体.我遇到的一个问题是我的一个表上有一个唯一的多列键.我希望看到的行为类似于upsert:当Hibernate持久化实体并检测到唯一约束违规时,它会执行更新.我们正在使用MySQL,它提供了INSERT ... ON DUPLICATE KEY UPDATE语法,但我不确定如何或者是否可以使用Hibernate来使用它?
我想我总是可以尝试插入,如果我捕获异常做更新,但这似乎是hacky和次优.有关干净方式的任何提示吗?
是否可以在查询后获取新的/更新的_id?示例代码:
$key = array( 'something' => 'unique' );
$data = array( '$inc' => array( 'someint' => 1 ) );
$mongodb->db->collection->update( $key, $data, array( 'upsert' => true ) );
Run Code Online (Sandbox Code Playgroud)
$ key没有持有新的/旧的_id对象,我认为$ data也不会因为它只是一个指令.
我在mongodb中有一组文档,expireAfterSeconds属性设置在日期类型索引上.
为了争论,文件将在一小时后过期.
当我更新此集合中的文档时,会发生以下哪种情况?
a)文件将在原始创建时间后一小时到期.
b)文件将在更新时间后一小时到期.
c)文档将在索引变量的时间后一小时到期,无论可能是什么.
d)以上都不是
我认为它是c,但找不到确认它的参考.我对么?这记录在哪里?
[编辑]:澄清一下,情况是我正在存储密码重置代码(应该过期.)并且我希望旧代码在请求新代码时停止工作.但这并不是很相关,因为我可以通过简单地删除旧事务来确保我想要的行为始终受到尊重.这个问题不是关于我当前的问题,而是关于Mongo的行为.
我用CTE写了一个'upsert'查询,看起来像这样:
WITH
new_data (id, value) AS (
VALUES (1, 2), (3, 4), ...
),
updated AS (
UPDATE table t set
value = t.value + new_data.value
FROM new_data
WHERE t.id = new_data.id
RETURNING t.*
)
INSERT INTO table (id, value)
SELECT id, value
FROM new_data
WHERE NOT EXISTS (
SELECT 1 FROM updated WHERE updated.id = new_data.id
)
Run Code Online (Sandbox Code Playgroud)
但是,我需要在我的应用程序中使用新值,但此查询不会返回任何内容.添加returning *到插入的末尾将返回已插入的所有行,但不会返回任何已更新的行.
那么,问题是(如何)我可以扩展它以返回已更新的行和插入的行?
编辑:当然我可以SELECT在一个事务中运行它然后运行,但我很想知道是否有单查询方式.
sql postgresql upsert common-table-expression postgresql-9.1
这是一个简单的pojo:
public class Description {
private String code;
private String name;
private String norwegian;
private String english;
}
Run Code Online (Sandbox Code Playgroud)
请参阅以下代码,upsert通过spring MongoTemplate 应用于MongoDb:
Query query = new Query(Criteria.where("code").is(description.getCode()));
Update update = new Update().set("name", description.getName()).set("norwegian", description.getNorwegian()).set("english", description.getEnglish());
mongoTemplate.upsert(query, update, "descriptions");
Run Code Online (Sandbox Code Playgroud)
生成Update对象的行Item手动指定类的每个字段.
但如果我的Item对象发生了变化,那么我的Dao图层会破裂
那么有没有办法避免这样做,以便我的Item类中的所有字段自动应用于更新?
例如
Update update = new Update().fromObject(item);
Run Code Online (Sandbox Code Playgroud)
请注意,我的pojo没有扩展DBObject.
在早期版本的MongoDB Java驱动程序中,要运行查询并对结果执行无序批量upsert,我们所做的就是:
BulkWriteOperation bulk = dbCollection.initializeUnorderedBulkOperation();
bulk.find(searchQuery).upsert().update(new BasicDBObject("$set", getDbObjectModel()));
Run Code Online (Sandbox Code Playgroud)
但是在版本3中,随着Bson Document支持和MongoCollection.bulkWrite()方法的引入,如何才能做到这一点?
我试过这个:
List<WriteModel<Document>> documentList = new ArrayList<>();
collection.bulkWrite(documentList, new BulkWriteOptions().ordered(false));
Run Code Online (Sandbox Code Playgroud)
但是,我需要upsert功能.
谢谢.
我想向ES发送n个upsert部分请求,这样的事情可能吗?因此,如果文档不存在,请插入我的部分文档.如果它已存在,请使用部分doc更新它.
使用批量助手,我尝试了很多变化,但它们都消除了现有的价值,转而支持新的价值.
data = [{
"_index": 'my_index',
"_type": 'my_type',
"_id": 12345,
"doc": {"newkey": 'newvalue'}
}]
helpers.bulk(es, data, index='my_index', doc_type='my_type')
Run Code Online (Sandbox Code Playgroud)
要么
data = [{
"_index": 'my_index',
"_type": 'my_type',
"_id": 12345,
"_source": {"newkey": 'newvalue'}
}]
helpers.bulk(es, data, index='my_index', doc_type='my_type')
Run Code Online (Sandbox Code Playgroud)
也不起作用.
我想在DynamoDB中'upsert'一个文档.也就是说,我想指定一个键和一组字段/值对.如果没有包含该密钥的文档,我想要使用该密钥创建的文档以及我指定的键/值对.如果存在具有该键的文档,我希望将我指定的字段设置为指定的值(如果之前不存在这些字段,则应添加它们).现有文档中的任何其他未指定字段应单独保留.
UpdateItem当我设置的字段/值对都是顶级字段时,似乎我可以通过调用很好地完成此操作.如果我有嵌套结构,UpdateItem只要结构存在,就可以设置嵌套字段.换句话说,如果我的现有文档有"foo": {},那么我可以"foo.bar": 42成功设置.
但是,我似乎无法设置"foo.bar": 42是否foo已经没有对象(例如在没有指定字段的文档的情况下,我的'upsert'表现为'insert'.
几年前我在AWS论坛上发现了一个关于AWS论坛的讨论,这似乎意味着我想要做的事情无法完成,但我希望最近有所改变,或者有人知道如何做到这一点?
我正在使用Postgresql 9.6.1,Plya!2.5和play-slick 2.0.2.
(我也使用slick-pg 0.14.3,但我不认为这会改变任何东西.)
我正在insertOrUpdate以非常直接的方式使用,但我仍然得到一个独特的例外.
我有一个非常简单的测试使用insertOrUpdate:如果我运行它几次,我总是得到一个SQL异常:
ERROR: duplicate key value violates unique constraint "ga_client_id_pkey"
Detail: Key (client_id)=(1885746393.1464005051) already exists
Run Code Online (Sandbox Code Playgroud)
但是,我的表定义client_id为主键:
def clientId = column[String]("client_id", O.PrimaryKey)
Run Code Online (Sandbox Code Playgroud)
并在sql中定义如下:
client_id TEXT NOT NULL UNIQUE PRIMARY KEY
Run Code Online (Sandbox Code Playgroud)
测试的功能只是:
db.run(gaClientIds.insertOrUpdate(gaClientId))
Run Code Online (Sandbox Code Playgroud)
并且控制器只是调用此方法而不执行任何其他操作.
一个奇怪的事情是,多次启动方法本身不会导致错误,但控制器会执行,尽管它只调用方法.
是insertOrUpdate华而不实的功能还不确定还是我失去了一些东西?
雪花是否支持使用类似UPDATE *or的语法更新/插入所有列INSERT *
MERGE INTO events
USING updates
ON events.eventId = updates.eventId
WHEN MATCHED THEN
UPDATE *
WHEN NOT MATCHED THEN
INSERT *
Run Code Online (Sandbox Code Playgroud)
类似于 Databricks 的做法:https ://docs.databricks.com/spark/latest/spark-sql/language-manual/delta-merge-into.html
或者我们是否必须列出每一列及其值?
当我尝试上述操作时出现错误
语法错误...意外的“*”。
并且文档没有多大帮助:https://docs.snowflake.com/en/sql-reference/sql/merge.html
谢谢,