I have the following two routes that take care of adding and getting a person on Firestore:
app.post('/api/person/add', (req, res) => {
const person = {
name: 'Bill Gates',
email: 'bill.gates#gmail.com',
description: "City: Redmond\nState: WA",
};
admin.firestore().collection('persons').doc(`/${req.body.id}/`).create(person);
res.status(200).json({ status: 'success' });
});
app.get('/api/person/get/:id', async (req, res) => {
const item = await admin.firestore().collection('persons').doc(req.params.id).get();
const person = item.data();
res.status(200).json(person);
});
If I run the following command for adding a person:
$ curl -s --request POST 'http://localhost:5001/happy-fox/us-central1/app/api/person/add' \
--header 'Content-Type: application/json' \
--data-raw '{
"id": 1,
"name": "Bill Gates",
"email": "bill.gates#gmail.com",
"description": "City: Redmond\nState: WA"
}'
I get:
{"status":"success"}
If I run the following command for getting a person:
$ curl -s --request GET 'http://localhost:5001/happy-fox/us-central1/app/api/person/get/1'
I get:
{"description":"City: Redmond\nState: WA","email":"bill.gates#gmail.com","name":"Bill Gates"}
Please notice the line break between the city name: Redmond and the word: State.
On my use case I need to modify the State manually (WA → NY) through the Firestore Panel UI, by doing the following:
My problem is: after updating that field, when I run the GET command again:
$ curl -s --request GET 'http://localhost:5001/happy-fox/us-central1/app/api/person/get/1'
I get:
{"description":"City: RedmondState: NY","email":"bill.gates#gmail.com","name":"Bill Gates"}
where you can see that the line break between the city name: Redmond and the word: State disappeared.
Is there any way I can do the update through the Firestore Panel UI without losing the line breaks?
Thanks!
Currently, Firestore does that to preserve the UI integrity. However, there's a workaround for that specific issue.
Manually put \n to the string when editing in Firestore UI. e.g:
"Redmond\nState: NY". By doing this, If you get/fetch the data, you'll be
getting Redmond\\nState instead. So you need to create a parser to
modify all \\n to n. sample code below:
var string = "Redmond\\nState: NY"
string = string.replace("\\n", "\n");
I would also suggest creating a Feature request for this issue.
Related
We loaded a SP list directly from an Access query and now when we try to run a list update with pnpjs I get an "Error code: -2130575163.List data validation failed" .
There are no required fields, no validation on any columns, and no Validation settings on the list. Is this not working because it was uploaded from Access?
Updating it similar to this:
const items = await sp.web.lists.getByTitle("MyList").items.top(1).filter("Title eq 'A Title'").get();
const updatedItem = await sp.web.lists.getByTitle("MyList").items.getById(items[0].Id).update({
my_id: mynewID,
})
Adding list items works with no issues. Updating a list item does not work.
Try this.
let list = sp.web.lists.getByTitle("MyList");
const i = await list.items.getById(1).update({
Title: "My New Title",
Description: "Here is a new description"
});
console.log(i);
Is items[0].Id valid ?
Please try to use console.log (items[0].Id) to check in Developer Tool.
I tested the same request in my side, my_id is a number field:
const items = await sp.web.lists.getByTitle("JqueryList").items.top(1).filter("Title eq 'My New Title'").get();
console.log(items);
let list = sp.web.lists.getByTitle("JqueryList");
const i = await list.items.getById(items[0].Id).update({
Title: "My New Title",
my_id: 1
});
I did resolve it - when you use the StrReverse function in Access and then upload that query to a SP list - the list type is corrupted.
To fix it I simply went in and changed the type from single line text to multiline - then back to single line of text.
I was then able to update the list item.
I'm writing my own CLI, which performs some actions against a MongoDB database using mongoose.
Everything works except for the fact that as soon as the query object is something other than {}, I get no results despite documents existing. See below for an example.
const program = require('commander');
const mongoose = require('mongoose');
const jsonParser = require('../helpers/json-parser');
program
.command('get <collection>')
.option('-q,--query <query>', 'MongoDB query object', jsonParser)
.option('-qo,--query-options [query-options]', 'MongoDB query options object', jsonParser)
.description('Returns documents from a MongoDB collection')
.action(action);
program.parse(process.argv);
function action(collection, options) {
let db;
mongoose.connect('<my-mongo-url>', { useNewUrlParser: true }).then(() => {
db = mongoose.connection.db;
console.log(options.query);
return db.collection(collection).find(options.query, options.queryOptions).toArray().then((docs) => {
console.log(docs);
mongoose.disconnect();
});
})
.catch((err) => {
if (db) {
mongoose.disconnect();
}
});
}
Running $ my-cli get users -q '{}' gives the following result:
[ { _id: 5cfe593b3bb7cb82644651f0,
email: 'foobar#gmail.com',
createdAt: 2019-06-10T13:20:59.784Z,
updatedAt: 2019-06-10T13:20:59.784Z,
role: 'user',
__v: 0 } ]
Running $ my-cli get users -q '{"_id": "5cfe593b3bb7cb82644651f0"}' gives the following result:
[]
Running $ my-cli get users -q '{"limit": 1}' gives the following result:
[]
Running $ my-cli get users -q '{"skip": 0}' gives the following result:
[]
I even tried doing db.collection(collection).find({_id: "5cfe593b3bb7cb82644651f0"}) directly in the code but it still only gives me an empty array.
I expect all of these queries to output the same thing but they don't. Why is this?
The _id in mongoDB is not string, actually it's an instance of ObjectId. So maybe you should go db.collection(collection).find({_id: ObjectId("5cfe593b3bb7cb82644651f0")}).
As for '{"limit": 1}' and '{"skip": 0}', I understand that you want to Modify the Cursor Behavior to limit or skip the search results.
However, the db.collection.find receive two params: query and projection, so passing '{"limit": 1}' or '{"skip": 0}' as the find secondary param maybe not what you want.
You are using Mongoose but not using Schemas and querying directly to MongoDB (so I don't understand the purpose of using it.). This way, you should compare the _id field with an ObjectId:
db.collection(collection).find({_id: ObjectId("5cfe593b3bb7cb82644651f0")})
or
$ my-cli get users -q '{"_id": ObjectId("5cfe593b3bb7cb82644651f0")}'
If I'm not wrong, the other queries are not running because you are passing options as query filters and you should use the -qo flag:
$ `my-cli get users -qo '{"limit": 1}'
I would like to list currently deleted documents in order to provide the ability to undelete one or more.
How can I query couchdb for deleted documents? I am actually using pouchdb.
Although this POST nicely describes how to query for and undelete a document, it requires an id of an existing doc.
I am looking for a way to query for all documents that have been deleted. The POST cites making a query for all changes. That query returns all documents that have been deleted IN ADDITION to any that have been edited/changed.
I am looking only for documents that have been deleted. Think querying for documents in the 'trash bin'. :)
Starting from couch 2.1.0, you can add various selectors to _changes feed. So your request to output only deleted documents will be:
curl -X POST -H "content-Type: application/json" "http://adm:pass#127.0.0.1:15984/tracks/_changes?filter=_selector" -d '{"selector": {"_deleted": true}}'
You can add a filter to the _changes feed in PouchDB: https://pouchdb.com/api.html#filtered-changes
var changes = db.changes({
filter: function(doc) {
return doc._deleted;
}
}).on('change', function(change) {
console.log(change.id);
})
For an all-in-one solution combining the open_revs tip from this answer, here's the TypeScript code I came up with:
const db = new PouchDB('my-db');
async function deletedDocIds(): Promise<string[]> {
const ret: string[] = [];
return new Promise((resolve, reject) => {
db.changes({filter: d => d._deleted})
.on('change', c => ret.push(c.id))
.on('complete', () => resolve(ret))
.on('error', e => reject(e));
});
}
async function deletedDocs() {
const ids = await deletedDocIds();
return Promise.all(ids.map(id => db.get(id, {revs: true, open_revs: 'all'}).then(x => {
const revs = (x[0].ok as any)._revisions;
const lastRev = (revs.start - 1) + '-' + revs.ids[1];
return db.get(id, {rev: lastRev}); // with Pouchdb keys too
})));
}
Calling deletedDocs() will return a promise of an array of all deleted docs as per the rev just prior to deletion.
N.B., the elements of the array will include PouchDb metadata as well as your document's keys.
N.B. 2, version 6.1.3 of DefinitelyTyped's TypeScript bindings for pouchdb-browser which I'm using here (should work for #types/pouchdb too though) doesn't seem to know about the _revisions key, hence the as any escape hatch.
N.B. 3, this should be trivial to manually translate to plain JS, just delete the type declarations and coercions (:, as, and whatever token follows these).
Resolved, the issue was with the PUT request , I had to specify the header properly and go on with one at a time.
curl -X PUT -H "Accept: application/json" -d "prenom=Maxwell" localhost:3000/contact/51df5cec5e88a2bbce7fac05
I'm trying to modify a mongodb document via coffeescript in a node.js application I'm currently working on and when I try :
curl -X PUT -d '{"nom": "House", "prenom": "Maxwell"}' localhost:3000/contact/51ddb907ae3267d6154a3e64
on this
{
"_id": "51ddb907ae3267d6154a3e64",
"archive": 1,
"nom": "Bir",
"prenom": "Sim"
}
The ID and the routes are correct, so I'm pretty sure the error lies in the javascript logic but I can't seem to grasp the right angle to work it. Here is the defective code :
exports.modifyContact = (req, res) ->
db.collection "data-center", (erreur, collection) ->
collection.update { _id: new mongo.BSONPure.ObjectID(req.params.id) }, { $set: req.body } , (erreur, resultat) ->
res.send resultat
res.end()
and the result is
{
"_id" : ObjectId("51df4ad424f6d9207cc3e2d5"),
"nom" : "Bir",
"nom": "House",
"prenom": "Maxwell" : "",
"prenom" : "Sim"
}
I can't seem to find an effective way to set missing value and modify value already in there. What is wrong ?
Give this a try instead:
exports.modify = (req, res) ->
fields = if (typeof req.body == 'string') then JSON.parse(req.body) else req.body
db.collection "data-center", (erreur, collection) ->
// check erreur here
collection.update { _id: new mongo.BSONPure.ObjectID(req.params.id) }, { $set: fields }, (erreur, resultat) ->
// check erreur here
res.send resultat
res.end()
It is important to note that inserting data directly from req.body without some sort of validation/content checking is not secure and should be avoided (even if it works as expected).
If you want to just "merge" a set of fields into an existing object you do it this way
test:PRIMARY> db.t2.insert({b:1})
test:PRIMARY> db.t2.update({b:1}, {$set: {a:1, c:2}})
test:PRIMARY> db.t2.find({b:1})
{ "_id" : ObjectId("520a3f10e2d66ef50d3b042b"), "a" : 1, "b" : 1, "c" : 2 }
Ah yeah and for the json issue, you cannot use the "original" object to return as json. You need to perform a findOne to retrieve the updated object from mongodb or change to using a findAndModify with the parameter new to get the changed object in a single operation. The existing object might well have have circular references.
According to the ES documentation, those 2 search request should get the same results:
GET
http://localhost:9200/app/users/_search?source={"query": {"term": {"email":"foo#gmail.com"}}}
POST
http://localhost:9200/app/users/_search
Post body :
{
"query": {
"term": {
"email":"foo#gmail.com"
}
}
}
But the first one gives no result while the second one gives me the expected result. I use ES version 0.19.10
Did anybody else have the same behavior ? Is this a bug ?
source is not a valid query string argument according to URI Search
Elasticsearch allows three ways to perform a search request...
GET with request body:
curl -XGET "http://localhost:9200/app/users/_search" -d '{
"query": {
"term": {
"email": "foo#gmail.com"
}
}
}'
POST with request body:
Since not all clients support GET with body, POST is allowed as well.
curl -XPOST "http://localhost:9200/app/users/_search" -d '{
"query": {
"term": {
"email": "foo#gmail.com"
}
}
}'
GET without request body:
curl -XGET "http://localhost:9200/app/users/_search?q=email:foo#gmail.com"
or (if you want to manually URL encode your query string)
curl -XGET "http://localhost:9200/app/users/_search?q=email%3Afoo%40gmail.com"
You should URL encode your query in the first case:
http://localhost:9200/app/users/_search?source=%7b%22query%22%3a+%7b%22term%22%3a+%7b%22email%22%3a%22foo%40gmail.com%22%7d%7d%7d
The above answers are not compatible with the Elastic search Version 6.0 and above.The ES introduced Strict Content type check from the version 6.0.
The link explains it:
https://www.elastic.co/blog/strict-content-type-checking-for-elasticsearch-rest-requests.
For curl, need to add -H'Content-Type: application/json' to the command line of any request that has a JSON body