How can i make a mongoDB subdocument have an unique id or incremented id? - json

Solved
I am having this MongoDB document:
{
_id: "5e3bf72db5074c1e205409f5",
todos: [
{
title: "title",
description: "description",
state: "state",
priority: "priority"
}
],
title: "test project"
}
and I want to keep the main '_id:' property for the project but also add an "_id:" or something of that sorts to my todos so that I can do CRUD operations on them alone easier. Is there a way of making a unique id or autoincremented id for them? The final result would look like this
Is there a way to do this? also, any other suggestions are appreciated.
{
_id: another unique id or autoincrement key,
title: "title",
description: "description",
state: "state",
priority: "priority"
}

Related

Fetch users data with related clients data in Yiii2 api

I need to get an API response, where each client row has its associated users' data in it. like this:
clients: [
{
id: 1
name: 'client_1',
users: [{ id: 1, name: 'user_1', clients_id: 1}, { id: 2, name: 'user_2',
clients_id: 1 }],
},
{
id: 2
name: 'client_2',
users: [{ id: 3, name: 'user_3', clients_id: 2}, { id: 4, name: 'user_4',
clients_id: 2 }],
},
]
How can I write Yii2 code for this result? Do query builder works here or do I need to use MySQL syntax?
I believe you have two tables those are related some how. You can achieve it by defining client relation in users table. One you defined the relation define extrafields function and add the relation there.
In url use expand query param and mention your relation there.
You are done!
Sample URLhttp://localhost/users?fields=id,email&expand=profile
Check the documentation

Couchbase N1QL query to get id of documents connected as a linked list

I have collection that contain documents with the following structure
{
id: "doc01",
property1: "",
nextCollection: "doc02"
prevCollection: null
},
{
id: "doc02",
property1: "",
nextCollection: "doc03",
prevCollection: "doc01"
},
{
id: "doc03",
property1: "",
nextCollection: null,
prevCollection: "doc02"
},
The above code contains three documents. What I want to do is to write a N1QL query that gets all documents in the list given doc01 id.
That is I want the return type to be
[
{
id: "doc01",
property1: "",
nextCollection: "doc02"
prevCollection: null
},
{
id: "doc02",
property1: "",
nextCollection: "doc03",
prevCollection: "doc01"
},
{
id: "doc03",
property1: "",
nextCollection: null,
prevCollection: "doc02"
}
]
How to write such query?
N1QL doesn't support hierarchical queries or recursive CTE.
Instead of single N1QL statement you can achieve this with the following options
Using N1QL UDF checkout https://www.couchbase.com/blog/traverse-hierarchy-user-defined-functions-in-7-1/
From application using SDK (As you know document keys you can use collection.get() avoid N1QL all together). You can even stop when recursive list detected circular and if list is huge control how many you want in the list.
Get the first document and add to the list
In loop until nextDocument is known value
get the document of key nextDocument
add to the list

Sequelize: How to return relationships as JSON attribute?

I have a simple database of articles and authors.
Each article is connected to author(s) through a belongsToMany relationship, for example:
Articles
id: 1
title: Test
Authors
id: 1
name: Foo
id: 2
name: Bar
Say, for example, that the article is joined to both authors.
Using sequelize, how can I have Articles.findAll() return the authors along with its details, for example:
"articles": [
{
"id": 1,
"title": "Test",
"author_ids": "[1,2]"
}
]
Use the include option in your query:
Articles.findAll({
include: [Author]
}).then(function(articles) {
console.log(articles[0].authors[0].author_id);
});

updateSingleValue() returns false, yet inputs are correct

I'm using updateSingleValue like this:
$updated = $this->app['storage']->updateSingleValue('suggestions', $id, 'votes', $value);
The $id and $value are set correctly (even if I set them to correct integers manually), and there definitely exists a suggestions contenttype with votes field. Yet, this function returns false, suggesting that !$this->isValidColumn($field, $contenttype) fails.
A suggestion in json format looks like this:
suggestion": {
"id": "25",
"values": {
"datechanged": "2015-01-03 13:25:02",
"id": "25",
"slug": "slug-o2sbdb",
"datecreated": "2015-01-03 13:25:02",
"datepublish": "2015-01-03 13:25:02",
"datedepublish": "1900-01-01 00:00:00",
"ownerid": "1",
"status": "published",
"title": "test title",
"description": "test description",
"votes": "0"
},
The suggestion contenttype looks like this:
suggestions:
name: Suggestions
slug: suggestions
singular_name: Suggestion
singular_slug: suggestion
default_status: publish
fields:
title:
label: Title
type: text
class: large
required: true
pattern: ".{2,255}" # see: http://html5pattern.com/
error: "The Title field is required, and must contain at least 2 characters"
description:
label: Description
type: textarea
votes:
label: Votes
type: integer
What can I be doing wrong here?
Found the problem here the contenttype passed into updateSingleValue needs to be the entire contenttype not just the slug 'suggestions'. You can fetch it via the storage class method:
$app['storage']->getContentType('suggestions')
then pass in the result of that to the updateSingleValue method.

How to list object key names with jsonpath?

I am using nodejs with jsonpath.
I have this json structure:
{
things:{
books: [
{name: "book1"},
{name: "book2"},
{name: "book3"},
{name: "book4"},
],
movies: [
{name: "movie1"},
{name: "movie2"},
{name: "movie3"},
{name: "movie4"},
]
}
}
I would like to know the jsonpath expression that returns an array with the key names of the things object. That would be:
["books","movies"]
For now, I am doing this:
Object.keys(jsonpath.eval(jsonStructure,"$.things").pop());
But I don't find it elegant... I should not need to get a copy the whole structure when I only need the key names.
jsonPath has new update jsonpath-plus
jsonpath-plus expands on the original specification to add some additional operators and makes explicit some behaviors the original did not spell out.
^ for grabbing the parent of a matching item
~ for grabbing property names of matching items (as array)
so to get proper output use this query things.*~
you can try here also https://jsonpath.com/
I don't believe there is a better solution than your own:
Object.keys(jsonpath.eval(jsonStructure,"$.things").pop());
I think the main misconception here is that you don't have to worry about this snippet "getting a copy of the whole structure", because you aren't copying the whole structure. You already have the entire object loaded into memory, jsonpath doesn't create a new copy, it simply returns a reference to the already existing object, i.e.:
jsonpath.eval(jsonStructure,"$.things").pop() === jsonStructure.things //true
Not exactly what you are asking for, but might still be relevant.
We use object-scan for this kind of task as it is much better suited for data processing and analyzing. Once you wrap your head around it that is (:
Anyways, here is how you could answer your question if you are willing to add another dependency
// const objectScan = require('object-scan');
const data = { things: { books: [ { name: 'book1' }, { name: 'book2' }, { name: 'book3' }, { name: 'book4' } ], movies: [ { name: 'movie1' }, { name: 'movie2' }, { name: 'movie3' }, { name: 'movie4' } ] } };
console.log(objectScan(['things.*'], { rtn: 'property' })(data));
// => [ 'movies', 'books' ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan#13.7.1"></script>
Disclaimer: I'm the author of object-scan
The syntax you used for give is wrong
to get keys in json path use "$.*~"
ex.
input:
{
"firstName": "John",
"lastName" : "doe",
"age" : 26
}
output:
[
"firstName",
"lastName",
"age"
]