Couchbase editing document using N1QL - couchbase

I have data like this in my Couchbase:
{
“mappings”: {
“/”: “Ana sayfa”
},
“platform”: “WEB”
}
I want to convert all data like this:
{
“/”: {“viewLabel”:“Ana Sayfa”}
“platform”: “WEB”
}
So I want to share old version:
{
“_class”: “com.commencis.appconnect.adminpanel.data.entity.ScreenNamesMappingEntity”,
“id”: “whitelabel::WEB::screenNamesMapping”,
“mappings”: {
“/”: “Ana sayfa”,
}
}
I want to create new document with above id:
( “id”: “whitelabel::WEB::screenNamesMapping”)
and delete the old one.
I want to create and convert like this:
{
“_class”: “com.commencis.appconnect.adminpanel.data.entity.ScreenNamesMappingEntity”,
“id”: “whitelabel::WEB::screenNamesMapping”,
“mappings”: {
“/”: { “viewLabel”: “Ana sayfa” } ,
}
I need to write script. I want to create new document with related id, then delete the old one, it could be multipe N1QL
I should not update the old data, new data should have new key, and I should edit the new key with the old one and delete the old one. I need to do with that way.

You can use the same document id by overwriting the current document, but there should be two repositories for both the entities.
oldRepository.findById("myid").ifPresent(e -> {
NewEntity ne = new NewEntity(e.id(), e.platform()...);
newRepository.save(ne); });

Related

Do I need to use Prisma's connect & disconnect API? Or is it not safe to just update my Relations via IDs as strings?

I am using prisma + mysql (on planetscale). When I link two items that are in different tables, I normally use connect or disconnect:
const getUser = await prisma.user.update({
where: {
id: 9
},
data: {
posts: {
| connect: {
| id: 11
| },
create: {
title: "My new post title"
}
}
}
})
I am wondering whether that's necessary or why that's necessary?
I also noticed that I can just update records in my database by updating the id (as a plain string), and it will still work. e.g.:
// example for updating a one-to-many relationship:
const getUser = await prisma.user.update({
where: {
id: 9
},
data: {
postId: "123192312i39123123"
}
}
})
... or if it's an explicit many-to-many relation, I can just edit the row in the relation-table & update the id.
Is this a bad way of doing things? Am I going to break something later down the line in doing it this way?
Your cloud provider is not relevant in the context of the question. It will not affect how your framework(prisma) behaves in updates.
I am wondering whether that's necessary or why that's necessary?
You have a user with a one to many relation: user => n posts.
You have an existing post in the db, and you want to add that post to the posts collection of a user.
That posts relation can be either explicit or implicit. The connect clause handles the addition of relation:
{
posts: {
connect: { id: 11 }
}
}
Without using the connect you'd have to create a new post:
{
posts: {
create: {
title: "My new post title"
}
}
}
update records in my database by updating the id (as a plain string)
Not sure what you mean here, mind sharing the schema?
or if it's an explicit many-to-many relation, I can just edit the row in the relation-table & update the id
If it's explicit many-to-many then it's OK to manually edit the id fields. As long as the ids are found and the relation makes sense, there's no problem with manual updates.

Create or update one to many relationship in Prisma

I'm trying to update a one to many relationship in Prisma. My schema looks like this
model A_User {
id Int #id
username String
age Int
bio String #db.VarChar(1000)
createdOn DateTime #default(now())
features A_Features[]
}
model A_Features {
id Int #id #default(autoincrement())
description String
A_User A_User? #relation(fields: [a_UserId], references: [id])
a_UserId Int?
}
I'm trying to add a couple of new features to user with id: 1, or update them if they are already there.
I'm trying doing something like
const post = await prisma.a_User.update({
where: { id: 1},
data: {
features: {
upsert: [
{ description: 'first feature'},
{ description: 'second feature'}
]
}
}
})
The compiler isn't happy, it tells me
Type '{ features: { upsert: { description: string; }[]; }; }' is not assignable to type '(Without<A_UserUpdateInput, A_UserUncheckedUpdateInput> & A_UserUncheckedUpdateInput) | (Without<...> & A_UserUpdateInput)'.
Object literal may only specify known properties, and 'features' does not exist in type '(Without<A_UserUpdateInput, A_UserUncheckedUpdateInput> & A_UserUncheckedUpdateInput) | (Without<...> & A_UserUpdateInput)'.ts(2322)
index.d.ts(1572, 5): The expected type comes from property 'data' which is declared here on type '{ select?: A_UserSelect; include?: A_UserInclude; data: (Without<A_UserUpdateInput, A_UserUncheckedUpdateInput> & A_UserUncheckedUpdateInput) | (Without<...> & A_UserUpdateInput); where: A_UserWhereUniqueInput; }'
(property) features: {
upsert: {
description: string;
}[];
}
I can't work out how to do it nor I can find clear help in the documentation. Any idea on how to implement it or where I can find some examples?
I'm providing my solution based on the clarifications you provided in the comments. First I would make the following changes to your Schema.
Changing the schema
model A_User {
id Int #id
username String
age Int
bio String #db.VarChar(1000)
createdOn DateTime #default(now())
features A_Features[]
}
model A_Features {
id Int #id #default(autoincrement())
description String #unique
users A_User[]
}
Notably, the relationship between A_User and A_Features is now many-to-many. So a single A_Features record can be connected to many A_User records (as well as the opposite).
Additionally, A_Features.description is now unique, so it's possible to uniquely search for a certain feature using just it's description.
You can read the Prisma Guide on Relations to learn more about many-to-many relations.
Writing the update query
Again, based on the clarification you provided in the comments, the update operation will do the following:
Overwrite existing features in a A_User record. So any previous features will be disconnected and replaced with the newly provided ones. Note that the previous features will not be deleted from A_Features table, but they will simply be disconnected from the A_User.features relation.
Create the newly provided features that do not yet exist in the A_Features table, and Connect the provided features that already exist in the A_Features table.
You can perform this operation using two separate update queries. The first update will Disconnect all previously connected features for the provided A_User. The second query will Connect or Create the newly provided features in the A_Features table. Finally, you can use the transactions API to ensure that both operations happen in order and together. The transactions API will ensure that if there is an error in any one of the two updates, then both will fail and be rolled back by the database.
//inside async function
const disconnectPreviouslyConnectedFeatures = prisma.a_User.update({
where: {id: 1},
data: {
features: {
set: [] // disconnecting all previous features
}
}
})
const connectOrCreateNewFeatures = prisma.a_User.update({
where: {id: 1},
data: {
features: {
// connect or create the new features
connectOrCreate: [
{
where: {
description: "'first feature'"
}, create: {
description: "'first feature'"
}
},
{
where: {
description: "second feature"
}, create: {
description: "second feature"
}
}
]
}
}
})
// transaction to ensure either BOTH operations happen or NONE of them happen.
await prisma.$transaction([disconnectPreviouslyConnectedFeatures, connectOrCreateNewFeatures ])
If you want a better idea of how connect, disconnect and connectOrCreate works, read the Nested Writes section of the Prisma Relation queries article in the docs.
The TypeScript definitions of prisma.a_User.update can tell you exactly what options it takes. That will tell you why the 'features' does not exist in type error is occurring. I imagine the object you're passing to data takes a different set of options than you are specifying; if you can inspect the TypeScript types, Prisma will tell you exactly what options are available.
If you're trying to add new features, and update specific ones, you would need to specify how Prisma can find an old feature (if it exists) to update that one. Upsert won't work in the way that you're currently using it; you need to provide some kind of identifier to the upsert call in order to figure out if the feature you're adding already exists.
https://www.prisma.io/docs/reference/api-reference/prisma-client-reference/#upsert
You need at least create (what data to pass if the feature does NOT exist), update (what data to pass if the feature DOES exist), and where (how Prisma can find the feature that you want to update or create.)
You also need to call upsert multiple times; one for each feature you're looking to update or create. You can batch the calls together with Promise.all in that case.
const upsertFeature1Promise = prisma.a_User.update({
data: {
// upsert call goes here, with "create", "update", and "where"
}
});
const upsertFeature2Promise = prisma.a_User.update({
data: {
// upsert call goes here, with "create", "update", and "where"
}
});
const [results1, results2] = await Promise.all([
upsertFeaturePromise1,
upsertFeaturePromise2
]);

How to check that field exists in every array item and is non-empty

Suppose I have a contract like this:
org.springframework.cloud.contract.spec.Contract.make {
request {
method "GET"
url "/api/profiles"
headers {
header('Accept': 'application/json;charset=UTF-8')
header('Content-Type': 'application/json;charset=UTF-8')
}
}
response {
status 200
headers {
header('Content-Type': 'application/json;charset=UTF-8')
}
body(
value(
stub(
'''\
[
{
"profile": "profile1",
},
{
"profile": "profile2",
}
]
'''
),
test(
[
[
"profile" : regex(nonEmpty()),
]
]
)
)
)
}
The test of "profile" : regex(nonEmpty()) only checks that there is at least one array entry with a profile attribute that is non empty.
I would like to test that all entries have a non-empty profile.
I already tried this using test matchers:
jsonPath('$.[*].profile', byRegex(nonEmpty()))
While this checks every profile field to be non-empty, it doesn't check whether such a field actually exists.
How can I test that a profile field exists in every array entry and that each one is non-empty?
I guess the easiest way will be to use byCommand in the testMatchers section and pass the list there. Then manually assert whatever you want programmatically.

create a random key at just one level

In Firebase, it's possible to create a random key using .childByAutoId()
let newEntry = FBRef.child("category").childByAutoId()
newEntry.setValue(["someValue": true])
This results in a json structure like this:
{
"category" : {
"random-key-generated-by-Firebase" : {
"someValue" : true
}
}
}
I was wondering is it possible to skip the last level and arrive at a structure like this instead?
{
"category" : {
"random-key-generated-by-Firebase" : true
}
}
For swift, first create a key reference
let key = ref.childByAutoId().key
Then create a childUpdate container
let childUpdates = ["/category/\(key)": true]
Finally update
ref.updateChildValues(childUpdates)

Is RethinkDB useful on partial updating json documents according rfc6902?

Please share your experience with partial updating of JSON document.At now I'm storing my JSON documents in MongoDB which looks like the following:
{
id: ObjectId(507f191e810c19729de860ea),
title: 'Sterling Archer',
comments: [
{text: 'Comment text', tags: ['tag1', 'tag2', 'tag3']},
{text: 'Comment test', tags: ['tag2', 'tag5']}
]
}
I need to frequently update my documents by using rfc6902 specification. Now, I do it not optimized way that looks the following (I use nodejs/express/mongoose and fast-json-patch module in this example):
var jsonpatch = require('fast-json-patch');
app.patch('/document/:id', function (req, res, next) {
var document_id = req.params.id;
// req.body.patch: { "op": "add", "path": "/comments/2", "value": {text: 'Comment test3', tags: ['tag4']}" }
var patches = req.body.patch;
// find document
Document.findById(document_id, function (err, document) {
// Applying patches
jsonpatch.apply(document, patches);
// Update whole document in MongoDB
Document.update({_id: document_id}, document, function (err) {
return res.status(200).send();
});
});
});
This is not optimize approach to patch documents due two queries in MongoDB and replacing whole document. So I'm looking for optimized approach and want to try RethinkDB for this task. Can you help me to inspect possibility of atomic document updating by using single query with RethinkDB? Or should I looks for another way of resolving my problem?
Please share your experience with partial updating of JSON document.
You just need one query in RethinkDB. Suppose you want to update the document whose id is 1 with the values {foo: 1, bar: 2}, and increment the field "count", you would do
r.table("data").get(1).update(function(doc) {
return doc.merge({foo: 1, bar:2, count: doc("count").add(1) })
})
While this update requires a unique query, the whole document will be updated.
If you have big documents, you can split them in multiple tables and perform joins later to retrieve the data.
You may be interested in reading this article about data modeling: http://www.rethinkdb.com/docs/data-modeling/