Mongoose hide fields AFTER populating - mongodb

Supposed I have this schema
class Room {
member_ids: [String]
owner_ids: [String]
}
And two virtual populates members and owners, which map to User schema (custom path, not _id)
I successfully get the data populated with this:
return this.roomModel
.findOne({ id: roomId })
.select('-_id -__v')
.populate('members owners', '-_id -__v')
.exec();
It now returns
{
"member_ids": [
"1",
"2"
],
"owner_ids": [
"1"
],
"owners": [
{
"id": "1",
"name": "User 1"
}
],
"members": [
{
"id": "1",
"name": "User 1"
},
{
"id": "2",
"name": "User 2"
}
]
}
The thing is, I don't want member_ids and owner_ids to end up in my response. I've tried using select('-member_ids -owner_ids') however the response did not have populated data anymore (I guess the select phase happens before the populate phase?). Is there anyway to achieve this, without resorting to manually removing the fields afterwards? Thank you.

Related

How to get two same attribute in azure cosmos db

I am creating a service using cosmos db.I am trying to creating a search query.
Query :
SELECT product.Name,product1.Name
FROM catalog
join industry in catalog.Industy
join category in industry.Category
join product1 in category.Product
join Subcategory in category.Subcategory
join product in Subcategory.Product
WHERE CONTAINS(product1.Name,'dg')
But i can not able to get both product and product list . it give me the error. Name already used.
error:
Object creation error, property name 'Name' specified more than once
Tree that i am trying to fetch :
[
{
"id": "string",
"industy": [
{
"id": "string",
"category": [
{
"id": "string",
"subcategory": [
{
"id": "string",
"product": [
{
"id": "string",
"methodOfPreparation": [
{
"id": "string",
}
],
"addons": [
{
"id": "string"
}
]
}
]
}
],
"product": [
{
"id": "string",
"methodOfPreparation": [
{
"id": "string"
}
],
"addons": [
{
"id": "string"
}
]
}
]
}
]
}
]
}
]
expect Output
product[],prodcut1[]
How can i solve this?
Firstly, the error could be solved if you use alias as #Zohar mentioned in the comment.
SELECT product.Name as productName,product1.Name as product1Name
FROM catalog
join industry in catalog.industy
join category in industry.category
join product1 in category.product
join Subcategory in category.subcategory
join product in Subcategory.product
The reason is that every retrieved item is an obj, the format of results is an array consists of many objects. The object can't accept duplicate column names.
If you want to get the format like product[],prodcut1[],you need to loop the result and assemble by yourself.(For example,use stored procedure)

Return Connected Node's Properties Instead of RID using OUT() in OrientDB

I am attempting to store a connected Node's data in a property of a selected Node in OrientDB via the OUT() projection. e.g.:
SELECT *, OUT("Has_Friend") AS Friends FROM Person
Given that a "Person" Node is connected to several "Friend" Nodes via the "Has_Friend" Edge, I would like the actual Friend Node properties to be stored in the "Friends" property on each Person Node returned by this query. e.g.:
{
"result": [
{
"Name": "Joe",
"Friends": [
{
"Name": "Ben",
"Title": "Mr."
},
{
"Name": "Stan",
"Title": "Dr."
}
]
},
{
"Name": "Tim",
"Friends": [
{
"Name": "Terrance",
"Title": "Esq."
},
{
"Name": "Sarah",
"Title": "Dr."
}
]
}
]
}
However, the query only stores the RID of each "Friend" Node in the "Friends" property rather than the actual data of that "Friend" Node. e.g.:
{
"result": [
{
"Name": "Joe",
"Friends": [
"#228:1",
"#227:1"
]
},
{
"Name": "Tim",
"Friends": [
"#225:1",
"#226:1"
]
}
]
}
I've searched the OrientDB documentation but am unsure as to how I might accomplish this. I suspect there's a way to nest queries for those Friend nodes inside of the primary query, but I'm not entirely sure how to do that. Any insight is greatly appreciated!
try to use expand() function. It would expands the document pointed by that link and give all properties of this document. So your query should looks like this one:
SELECT expand(in("Has_Friend")) AS Friend FROM Person

Join different nodes to observe them at once with firebase

I'm trying to do a sample application with firebase and I don't have quite understand how I should retrieve nested-flattered data.
Let's suppose I have a db like this
{
"users": {
"user-1": {
"email": "email1",
"matches": [
"match-1",
"match-2"
]
},
"user-2": {
"email": "email2",
"matches": [
"match-1",
"match-2"
]
},
"user-3": {
"email": "email3",
"matches": [
"match-2"
]
}
},
"matches": {
"match-1": {
"name": "Match 1",
"users": [
"user-1",
"user-2"
]
},
"match-2": {
"name": "Match 2",
"users": [
"user-1",
"user-2",
"user-3"
]
}
}
}
and I want to get all the match of the user-1.
What I'm doing now is observe users.user-1.matches to get the matches list and then observe every match so the final flow is:
observe users.user-1.matches
observe matches.match-1
observe matches.match-2
...
The question is: how can I optimize this flow? (like making something like the sql join)
My idea is to get something like this
{
"users": {
"user-1": {
"email": "email1",
"matches": {
"match-1": {
"name": "Match 1",
"users": [
"user-1",
"user-2"
]
},
"match-2": {
"name": "Match 2",
"users": [
"user-1",
"user-2",
"user-3"
]
}
}
}
}
}
So I can observer the whole structure at once.
I'm using firebase on iOS with swift but feel free to reply in every language you like.
Thanks.
The answer linked in the comment is an answer, but let's simplify. Let's create a users node to store the users and a matches node to track the matches they played in.
Then we'll do a query to retrieve which matches user-1 played in:
users
user-1
name: "some name"
email: "somename#thing.com"
user-2
name: "another name"
email: "anothername#thing.com"
user-3
name: "cool name"
email: "coolname#thing.com"
and then the matches node
matches
match-1
name: "Match 1"
users
user-1: true
user-2: true
match-2
name: "Match 2"
users
user-1: true
user-2: true
user-3: true
match-3
name: "Match 3"
users
user-2: true
user-3: true
As you can see, we've structured the data to directly address our query
matchesRef.queryOrdered(byChild: "users/user-1").queryEqual(toValue: true)
.observe(.value, with: { snapshot in
print(snapshot)
});
and the snapshot will contain the nodes match-1 and match-2 but not match-3

How can I query an indexed object list in mongodb?

I have some documents in the "company" collection structured this way :
[
{
"company_name": "Company 1",
"contacts": {
"main": {
"email": "main#company1.com",
"name": "Mainuser"
},
"store1": {
"email": "store1#company1.com",
"name": "Store1 user"
},
"store2": {
"email": "store2#company1.com",
"name": "Store2 user"
}
}
},
{
"company_name": "Company 2",
"contacts": {
"main": {
"email": "main#company2.com",
"name": "Mainuser"
},
"store1": {
"email": "store1#company2.com",
"name": "Store1 user"
},
"store2": {
"email": "store2#company2.com",
"name": "Store2 user"
}
}
}
]
I'm trying to retrieve the doc that have store1#company2.com as a contact but cannot find how to query a specific value of a specific propertie of an "indexed" list of objects.
My feeling is that the contacts lists should not not be indexed resulting in the following structure :
{
"company_name": "Company 1",
"contacts": [
{
"email": "main#company1.com",
"name": "Mainuser",
"label": "main"
},
{
"email": "store1#company1.com",
"name": "Store1 user",
"label": "store1"
},
{
"email": "store2#company1.com",
"name": "Store2 user",
"label": "store2"
}
]
}
This way I can retrieve matching documents through the following request :
db.company.find({"contacts.email":"main#company1.com"})
But is there anyway to do a similar request on document using the previous structure ?
Thanks a lot for your answers!
P.S. : same question for documents structured this way :
{
"company_name": "Company 1",
"contacts": {
"0": {
"email": "main#company1.com",
"name": "Mainuser"
},
"4": {
"email": "store1#company1.com",
"name": "Store1 user"
},
"1": {
"email": "store2#company1.com",
"name": "Store2 user"
}
}
}
Short answer: yes, they can be queried but it's probably not what you want and it's not going to be really efficient.
The document structure in the first and third block is basically the same - you have an embedded document. The only difference between are the name of the keys in the contacts object.
To query document with that kind of structure you will have to do a query like this:
db.company.find({ $or : [
{"contacts.main.email":"main#company1.com"},
{"contacts.store1.email":"main#company1.com"},
{"contacts.store2.email":"main#company1.com"}
]});
This query will not be efficient, especially if you have a lot of keys in the contacts object. Also, creating a query will be unnecessarily difficult and error prone.
The second document structure, with an array of embedded objects, is optimal. You can create a multikey index on the contacts array which will make your query faster. The bonus is that you can use a short and simple query.
I think the easiest is really to shape your document using the structure describe in your 2nd example : (I have not fixed the JSON)
{
"company_name": "Company 1",
"contacts":{[
{"email":"main#company1.com","name":"Mainuser", "label": "main", ...}
{"email":"store1#company1.com","name":"Store1 user", "label": "store1",...}
{"email":"store2#company1.com","name":"Store2 user", "label": "store2",...}
]}
}
like that you can easily query on email independently of the "label".
So if you really want to use the other structure, (but you need to fix the JSON too) you will have to write more complex code/aggregation pipeline, since we do not know the name and number of attributes when querying the system. Theses structures are also probably hard to use by the developers independently of MongoDB queries.
Since it was not clear let me show what I have in mind
db.company.save(
{
"company_name": "Company 1",
"contacts":[
{"email":"main#company1.com","name":"Mainuser", "label": "main"},
{"email":"store1#company1.com","name":"Store1 user", "label": "store1"},
{"email":"store2#company1.com","name":"Store2 user", "label": "store2"}
]
}
);
db.company.save(
{
"company_name": "Company 2",
"contacts":[
{"email":"main#company2.com","name":"Mainuser", "label": "main"},
{"email":"store1#company2.com","name":"Store1 user", "label": "store1"},
{"email":"store2#company2.com","name":"Store2 user", "label": "store2"}
]
}
);
db.company.ensureIndex( { "contacts.email" : 1 } );
db.company.find( { "contacts.email" : "store1#company2.com" } );
This allows you to store many emails, and query with an index.

extjs nested data view select a node

i have data view with following tpl.
<tpl for=".">
<tpl for="departments">
{title}
</tpl>
<tpl for="records">
<div class="thumb-wrap">
{name}
</div>
</tpl>
</tpl>
and my json redear like this
reader : new Ext.data.JsonReader(
{
root : 'data',
},
[
'departments' ,
'records'
]
),
and my item selectore in on my recordes
itemSelector : 'div.thumb-wrap',
and this is my json data
{
"success": true,
"data": [
{
"departments": [
{
"title": "name"
}
],
"records": [
{
"name": "name"
},
{
"name": "name"
}
]
},
{
"departments": [
{
"title": "name"
}
],
"records": [
{
"name": "name"
}
]
}
]
}
how cat i select my records in data view with extjs?
and how can i get selected recordes ?
i used getSelectedRecords() but it return array of departments and records.
tnx
I'm pretty sure that getSelectedRecords() is deprecated on ExtJS 4.
You can try doing something like this:
var records = data.getRecords();
That will return a Ext.data.Model[]. Than, you can access all the properties like an usual model:
record.get('departments');
record.get('records');
You are working against the system here with your record structure. DataView wants one record to correspond with one selectable item. But you want to have multiple selectable items inside one record. Doesn't work - the API was not designed for such a thing.
Your options seem to be:
Create a separate DataView component for each set of records.
Create your own DataView component that can handle grouping.
Use Grid with GroupingView. You have to change your record structure to something like below, but it's the easiest option to get working. Though... you have to sacrifice quite a bit of flexibility offered by DataView.
"data": [
{
{
"department": "Department 1"
"name": "record 1"
},
{
"department": "Department 1"
"name": "record 2"
},
{
"department": "Department 2"
"name": "record 1"
},
{
"department": "Department 2"
"name": "record 2"
},
]
}