Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
{
"action" : "get",
"application" : "2c5ca3b0-be74-11e4-8ff3-f7af49a474ef",
"params" : {
"ql" : [ "select * where username='pqr'" ]
},
"path" : "/logs",
"uri" : "https://api.usergrid.com/serv-d/demo1/logs",
"entities" : [ {
"uuid" : "97b0fd0a-be74-11e4-9324-b3bd8af7859e",
"type" : "log",
"created" : 1425036869840,
"modified" : 1425036869840,
"metadata" : {
"path" : "/logs/97b0fd0a-be74-11e4-9324-b3bd8af7859e"
},
"password" : "pqr",
"username" : "pqr"
}],
"timestamp" : 1425359738746,
"duration" : 15,
"organization" : "serv-d",
"applicationName" : "demo1",
"count" : 1
}
This is the server side response to my app and I want to get the user name and password values only.
Use JSON.parse() to parse the JSON response into a Javascript object. Then you can access the properties.
var obj = JSON.parse(response);
The username and password are in an array that's in the entities property, so you can access them as:
var username = obj.entities[0].username;
var password = obj.entities[0].password;
Get the data in a variable, say in variable data.
var data = {
"action" : "get",
"application" : "2c5ca3b0-be74-11e4-8ff3-f7af49a474ef",
"params" : {
"ql" : [ "select * where username='pqr'" ]
},
"path" : "/logs",
"uri" : "https://api.usergrid.com/serv-d/demo1/logs",
"entities" : [ {
"uuid" : "97b0fd0a-be74-11e4-9324-b3bd8af7859e",
"type" : "log",
"created" : 1425036869840,
"modified" : 1425036869840,
"metadata" : {
"path" : "/logs/97b0fd0a-be74-11e4-9324-b3bd8af7859e"
},
"password" : "pqr",
"username" : "pqr"
}],
"timestamp" : 1425359738746,
"duration" : 15,
"organization" : "serv-d",
"applicationName" : "demo1",
"count" : 1
};
//logging username and password fields
console.log(data.entities[0].username, data.entities[0].password);
JSON behaves like key value pair kind of collection. Assign this Json to Javascript variable and then you can get the values of JSON with respective key like
var myJson =
{
"action" : "get", "application" : "2c5ca3b0-be74-11e4-8ff3-
f7af49a474ef", "params" : { "ql" : [ "select * where
username='pqr'" ] }, "path" : "/logs", "uri" :
"https://api.usergrid.com/serv-d/demo1/logs", "entities" : [
{ "uuid" : "97b0fd0a-be74-11e4-9324-b3bd8af7859e", "type" :
"log", "created" : 1425036869840, "modified" :
1425036869840, "metadata" :
{ "path" : "/logs/97b0fd0a-be74-11e4-9324-b3bd8af7859e"
}, "pas sword" : "pqr", "username" : "pqr"
}], "timestamp" : 1425359738746, "duration" : 15,
"organization" : "serv-d", "applicationName" : "demo1",
"count" : 1 };
var action = myJSON.action;
var uri = myJSON.uri; and so on..
Assuming you store it as "obj", then you can do obj.entities[0].username (and likewise for password.
Assuming you are referring it as data, You can use data.entities[0].username to access username.
var data = {
"action": "get",
"application": "2c5ca3b0-be74-11e4-8ff3-f7af49a474ef",
"params": {
"ql": [
"select * where username='pqr'"
]
},
"path": "/logs",
"uri": "https://api.usergrid.com/serv-d/demo1/logs",
"entities": [
{
"uuid": "97b0fd0a-be74-11e4-9324-b3bd8af7859e",
"type": "log",
"created": 1425036869840,
"modified": 1425036869840,
"metadata": {
"path": "/logs/97b0fd0a-be74-11e4-9324-b3bd8af7859e"
},
"password": "pqr",
"username": "pqr"
}
],
"timestamp": 1425359738746,
"duration": 15,
"organization": "serv-d",
"applicationName": "demo1",
"count": 1
};
alert(data.entities[0].username)
alert(data.entities[0].password)
var yourData = {
"action" : "get",
"application" : "2c5ca3b0-be74-11e4-8ff3-f7af49a474ef",
"params" : {
"ql" : [ "select * where username='pqr'" ]
},
"path" : "/logs",
"uri" : "https://api.usergrid.com/serv-d/demo1/logs",
"entities" : [ {
"uuid" : "97b0fd0a-be74-11e4-9324-b3bd8af7859e",
"type" : "log",
"created" : 1425036869840,
"modified" : 1425036869840,
"metadata" : {
"path" : "/logs/97b0fd0a-be74-11e4-9324-b3bd8af7859e"
},
"password" : "pqr",
"username" : "pqr"
}],
"timestamp" : 1425359738746,
"duration" : 15,
"organization" : "serv-d",
"applicationName" : "demo1",
"count" : 1
}
Because username and password is data of entities- that is an array of one element member
you may access the username data
var username = yourData.entities[0].username
Similarly for password
Related
Hii I am trying to save my HTML form data in the database. I create a JSON file for Dynamic fields and I bind it but there is some problem that's why data is not save. When I save the data, the same data is saved as it is in the JSON file as if I entered some string value in the input field, it is not saved but the original string is the same.
<div>
<p *ngFor="let item of doclist">
{{ item.label }}
<ejs-checkbox [(ngModel)]="item.value" id="item.value" name="item.value">
{{ item.value }}
</ejs-checkbox>
<ejs-textbox *ngIf="item.value == true && !false"[(ngModel)]="item.comment"
name="item.comment">
{{ item.comment }}
</ejs-textbox>
</p>
</div>
public doclist : {}[] = db;
public doc = JSON.stringify(this.doclist);
this.salesToOpsHand.documentList = this.doc;
`// documentList in that i have to save my all json string value so i write here doc values == documentList`
this is my db.json file
[
{
"name" : "IsSpecifications",
"label" : "isSpecifications() ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "IsDrawSchedule",
"label" : "Drawings/Schedules ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "TqRfi",
"label" : "TQ’s / RFI’s ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "InsEnqReqQouInfor",
"label" : "Install Enquiry / request to quote information ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "PanEnqReqQouInfor",
"label" : "Panel Enquiry / request to quote information ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "PanSubContQuot",
"label" : "Panel Sub Contractor Quotation ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "MccSchedule",
"label" : "MCC Schedules ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "ScPackQuot",
"label" : "Other S/C Package Quotations ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "OthrdPartyQuot",
"label" : "Other 3rd Party Quotations ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "EquipSchedule",
"label" : "Equipment Schedules ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "PointSchedul",
"label" : "Points Schedules ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "ValveSchedul",
"label" : "Valve Schedules ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "IdentRiskOpport",
"label" : "Identifed Risks and Opportunities (INCL. VALUE ENGINEERING) ",
"value" : false,
"type" : "checkbox",
"comment" : ""
},
{
"name" : "InstSubContQuot",
"label" : "Install Sub Contractor Quotation ",
"value" : false,
"type" : "checkbox",
"comment" : ""
}
]
`if someone knows where is am doing a mistake please help me
here I try angular and JSON file and save the value in form of a string in the server side`
I just wanted to fetch that data which coming from this https://food-ordring-af14d-default-rtdb.firebaseio.com/order the data is in the form of JSON and it looks like that
{
"-MzJLd0sSssh9tbJbjUS" : {
"orderDetails" : [ {
"amount" : 4,
"id" : "m1",
"name" : "Shushi",
"price" : 22.99
}, {
"amount" : 3,
"id" : "m2",
"name" : "Schnitzel",
"price" : 16.5
} ],
"user" : {
"address" : "A-132 shiv vihar,rishal garden,Nangloi",
"city" : "New delhi",
"name" : "Bhupender Sharma",
"postal" : "110041"
}
},
"-MzJOf_52xhRQi3izTRV" : {
"orderDetails" : [ {
"amount" : 2,
"id" : "m3",
"name" : "Barbecue Burger",
"price" : 12.99
}, {
"amount" : 2,
"id" : "m4",
"name" : "Green Bowl",
"price" : 18.99
} ],
"user" : {
"address" : "Nangloi",
"city" : "New delhi",
"name" : "ANkit",
"postal" : "445575"
}
}
}
Try this code .. here some example
const fetchdata = async()=>{
const response = await fetch('https://jsonplaceholder.typicode.com/todos')
const jdata = await response.json()
console.log(jdata)
}
fetchdata()
I need to make a query where it matches a specific value of an array. Not all the values of the array but only one. I know in mongo there is a $in operator so you can match 1 value of the array.
I have written my code something like this:
const getSearch = async (req,res) => {
try{
//query = { establishment: { name: "foodtruck" }, configuration: { name: "lineal" } }
console.log(query)
let doesExist = await Kitchen.find({ "establishment": { "name": { "$in": ["foodtruck","salon"] } }})
console.log(doesExist)
}catch(err){
throw err
}
}
In my local mongo i have different objects that matches the establishment name. Here they are:
db.kitchens.find()
{ "_id" : ObjectId("6084ca4c49ddab30473a7396"), "anafes" : { "quantity" : "1" }, "norms" : [ "norm5", "norm4" ], "availableDays" : [ "4/26/2021", "4/27/2021", "4/28/2021", "4/29/2021", "4/30/2021", "5/1/2021", "5/10/2021", "5/11/2021", "5/12/2021", "5/13/2021", "5/14/2021", "5/15/2021", "5/16/2021", "5/17/2021", "5/18/2021", "5/19/2021", "5/2/2021", "5/20/2021", "5/21/2021", "5/22/2021", "5/3/2021", "5/4/2021", "5/5/2021", "5/6/2021", "5/7/2021", "5/8/2021", "5/9/2021" ], "created_at" : ISODate("2021-04-25T01:26:29.542Z"), "updated_at" : ISODate("2021-04-25T01:26:29.542Z"), "deleted_at" : null, "establishment" : { "name" : "delivery" }, "dimensions" : { "name" : "40" }, "configuration" : { "name" : "lineal" }, "pictures" : [ { "_id" : ObjectId("6084ca4c49ddab30473a7397"), "url" : "https://hood-bucket-2021.s3.sa-east-1.amazonaws.com/images/1619315274721.jpg" } ], "timePrices" : [ { "_id" : ObjectId("6084ca4c49ddab30473a7398"), "time" : "perWeek", "price" : "5000" } ], "check_in" : { "from" : "00:00", "to" : "00:00" }, "check_out" : { "from" : "00:00", "to" : "00:00" }, "ovens" : { "name" : "convection", "brand" : "adidas" }, "location" : { "city" : "Buenos Aires", "province" : "Buenos Aires", "street" : "Teodoro Garcia", "number" : "1930", "coords" : [ { "_id" : ObjectId("6084ca4c49ddab30473a7399"), "lat" : "-34.5650491", "lng" : "-58.4415115" } ], "floor" : "9", "postal" : 1426 }, "type_of_time" : [ { "_id" : ObjectId("6084ca4c49ddab30473a739a"), "time" : "perWeek" } ], "host" : ObjectId("605f4e36d8281726d9be3ad3"), "__v" : 0 }
{ "_id" : ObjectId("6089f8a7bda5898d50876791"), "anafes" : { "quantity" : "1" }, "norms" : [ "norm2", "norm3", "norm8" ], "availableDays" : [ "4/30/2021", "5/1/2021", "5/10/2021", "5/11/2021", "5/12/2021", "5/13/2021", "5/14/2021", "5/15/2021", "5/16/2021", "5/17/2021", "5/18/2021", "5/19/2021", "5/2/2021", "5/20/2021", "5/21/2021", "5/22/2021", "5/23/2021", "5/24/2021", "5/25/2021", "5/26/2021", "5/27/2021", "5/28/2021", "5/29/2021", "5/3/2021", "5/30/2021", "5/31/2021", "5/4/2021", "5/5/2021", "5/6/2021", "5/7/2021", "5/8/2021", "5/9/2021", "7/1/2021", "7/10/2021", "7/11/2021", "7/12/2021", "7/13/2021", "7/14/2021", "7/15/2021", "7/16/2021", "7/17/2021", "7/18/2021", "7/19/2021", "7/2/2021", "7/20/2021", "7/21/2021", "7/22/2021", "7/23/2021", "7/24/2021", "7/25/2021", "7/26/2021", "7/27/2021", "7/28/2021", "7/29/2021", "7/3/2021", "7/30/2021", "7/31/2021", "7/4/2021", "7/5/2021", "7/6/2021", "7/7/2021", "7/8/2021", "7/9/2021" ], "created_at" : ISODate("2021-04-28T23:56:46.101Z"), "updated_at" : ISODate("2021-04-28T23:56:46.102Z"), "deleted_at" : null, "establishment" : { "name" : "foodtruck" }, "dimensions" : { "name" : "50" }, "configuration" : { "name" : "general" }, "pictures" : [ { "_id" : ObjectId("6089f8a7bda5898d50876792"), "url" : "https://hood-bucket-2021.s3.sa-east-1.amazonaws.com/images/1619654809186.jpg" }, { "_id" : ObjectId("6089f8a7bda5898d50876793"), "url" : "https://hood-bucket-2021.s3.sa-east-1.amazonaws.com/images/1619654809259.jpg" } ], "timePrices" : [ { "_id" : ObjectId("6089f8a7bda5898d50876794"), "time" : "perDay", "price" : "10000" } ], "check_in" : { "from" : "10:00", "to" : "12:00" }, "check_out" : { "from" : "15:00", "to" : "17:00" }, "ovens" : { "name" : "static", "brand" : "adidas" }, "location" : { "city" : "buenos aires", "coords" : [ { "_id" : ObjectId("6089f8a7bda5898d50876795"), "lat" : "-34.5659098", "lng" : "-58.43880350000001" } ], "province" : "buenos aires", "street" : "Olleros", "number" : "1870", "floor" : "4", "postal" : 1426 }, "type_of_time" : [ { "_id" : ObjectId("6089f8a7bda5898d50876796"), "time" : "perDay" } ], "host" : ObjectId("605f4e36d8281726d9be3ad3"), "__v" : 0 }
{ "_id" : ObjectId("608a09e29eda52a6cdc7d663"), "anafes" : { "quantity" : "1" }, "norms" : [ "norm1", "norm2", "norm4" ], "availableDays" : [ "4/30/2021", "6/1/2021", "6/10/2021", "6/11/2021", "6/12/2021", "6/13/2021", "6/14/2021", "6/15/2021", "6/16/2021", "6/17/2021", "6/18/2021", "6/19/2021", "6/2/2021", "6/20/2021", "6/21/2021", "6/22/2021", "6/23/2021", "6/24/2021", "6/25/2021", "6/26/2021", "6/27/2021", "6/28/2021", "6/29/2021", "6/3/2021", "6/30/2021", "6/4/2021", "6/5/2021", "6/6/2021", "6/7/2021", "6/8/2021", "6/9/2021" ], "created_at" : ISODate("2021-04-29T00:47:45.376Z"), "updated_at" : ISODate("2021-04-29T00:47:45.376Z"), "deleted_at" : null, "establishment" : { "name" : "foodtruck" }, "dimensions" : { "name" : "50" }, "configuration" : { "name" : "lineal" }, "pictures" : [ { "_id" : ObjectId("608a09e29eda52a6cdc7d664"), "url" : "https://hood-bucket-2021.s3.sa-east-1.amazonaws.com/images/1619659217736.jpg" }, { "_id" : ObjectId("608a09e29eda52a6cdc7d665"), "url" : "https://hood-bucket-2021.s3.sa-east-1.amazonaws.com/images/1619659217747.jpg" }, { "_id" : ObjectId("608a09e29eda52a6cdc7d666"), "url" : "https://hood-bucket-2021.s3.sa-east-1.amazonaws.com/images/1619659217668.jpg" } ], "timePrices" : [ { "_id" : ObjectId("608a09e29eda52a6cdc7d667"), "time" : "perDay", "price" : "5000" }, { "_id" : ObjectId("608a09e29eda52a6cdc7d668"), "time" : "perWeek", "price" : "15000" } ], "check_in" : { "from" : "07:00", "to" : "08:00" }, "check_out" : { "from" : "14:00", "to" : "20:00" }, "ovens" : { "name" : "convection", "brand" : "super", "model" : "adibas" }, "location" : { "city" : "BUenos aires", "coords" : [ { "_id" : ObjectId("608a09e29eda52a6cdc7d669"), "lat" : "-34.5793959", "lng" : "-58.40673389999999" } ], "province" : "Buenos aires", "street" : "Avenida del libertador", "number" : "2550", "floor" : "10", "postal" : 1426 }, "type_of_time" : [ { "_id" : ObjectId("608a09e29eda52a6cdc7d66a"), "time" : "perDay" }, { "_id" : ObjectId("608a09e29eda52a6cdc7d66b"), "time" : "perWeek" } ], "host" : ObjectId("605f4e36d8281726d9be3ad3"), "__v" : 0 }
But when I run this query:
let doesExist = await Kitchen.find({ "establishment": { "name": { "$in": ["foodtruck","salon"] } }})
it does not match anything, but if I run this query:
let doesExist = await Kitchen.find({ "establishment": { "name": "foodtruck" }})
It does match. I don't understand what I am doing wrong, or why the $in operator is not.
working.
Can someone help me?????????
let doesExist = await Kitchen.find({"establishment.name": {"$in": ["foodtruck","salon"]}})
I am using mongoose and node and I am trying to paginate data from sub-documents. I am able to limit subdocuments, but not skip them.
The versions I am using are:
Mongo 3.0.0
Node 0.10.33
Mongoose 3.9.7
The Data
[{
"name" : "Ranger Table",
"_id" : ObjectId("550234d3d06039d507d238d8"),
"body" : [
{
"name" : "Jason",
"colour" : "Red",
"animal" : "T-rex",
"_id" : ObjectId("550234d3d06039d507d238de")
},
{
"name" : "Billy",
"colour" : "Blue",
"animal" : "Triceratops",
"_id" : ObjectId("550234d3d06039d507d238dd")
},
{
"name" : "Zach",
"colour" : "Black",
"animal" : "Mastadon",
"_id" : ObjectId("550234d3d06039d507d238dc")
},
{
"name" : "Tommy",
"colour" : "Green",
"animal" : "Dragon"
"_id" : ObjectId("550234d3d06039d507d238d9")
}
]
},{
"name" : "Bot Table",
"_id" : ObjectId("5502d205184cd74033f64e6b"),
"body" : [
{
"name" : "Optimus",
"team" : "Autobots",
"class" : "Leader",
"_id" : ObjectId("550234d3d06039d507d238d9")
},
{
"name" : "Bumblebee",
"team" : "Autobots",
"class" : "Scout",
"_id" : ObjectId("550234d3d06039d507d238da")
},
{
"name" : "Astrotrain",
"team" : "Decepticons",
"class" : "Transport",
"_id" : ObjectId("550234d3d06039d507d238db")
}
]
}]
The Code
var BodySchema = new Schema({random: String},{strict:false});
var FeedSchema = new Schema({
name: String,
body:[BodySchema]
});
var feed = mongoose.model('Feed', FeedSchema);
feed.find({_id:'550234d3d06039d507d238d8'})
.populate({
"path":"body",
"options":{
limit:2, //This works fine
skip:2 //This doesn't work
}
})
.exec(function(err, result){
if(err){return(res.send(500, err))}
res.send(result);
});
The Result
The above code DOES limit the number of "body" sub-documents to 2, but doesn't skip any.
The code above returns this:
{
"name" : "Ranger Table",
"_id" : ObjectId("550234d3d06039d507d238d8"),
"body" : [
{
"name" : "Jason",
"colour" : "Red",
"animal" : "T-rex",
"_id" : ObjectId("550234d3d06039d507d238de")
},
{
"name" : "Billy",
"colour" : "Blue",
"animal" : "Triceratops",
"_id" : ObjectId("550234d3d06039d507d238dd")
}
]
}
But it should return this:
{
"name" : "Ranger Table",
"_id" : ObjectId("550234d3d06039d507d238d8"),
"body" : [
{
"name" : "Zach",
"colour" : "Black",
"animal" : "Mastadon",
"_id" : ObjectId("550234d3d06039d507d238dc")
},
{
"name" : "Tommy",
"colour" : "Green",
"animal" : "Dragon"
"_id" : ObjectId("550234d3d06039d507d238d9")
}
]
}
The solution that I found was to use aggregate and specify the name of the subdocument with $unwind.
http://docs.mongodb.org/manual/reference/operator/aggregation/
feed.aggregate([
{'$match':{_id:id('550234d3d06039d507d238d8')}},
{'$unwind':'$body'},
{'$skip':2},
{'$limit':2},
], function(err, result){
if(err){return(res.send(500, err))}
res.send(result);
});
We have a mongo collection messages that is in the following format...
/* 0 */
{
"text" : "A message to John",
"created" : ISODate("2015-01-29T23:50:10.488Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
/* 1 */
{
"text" : "Another message to John",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin fowler"
},
}
/* 2 */
{
"text" : "Just another message to Jerry",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Jerry Jones"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
/* 2 */
{
"text" : "Message to Martin Fowler",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Martin Fowler"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Jerry Jones"
},
}
We need to display the data above in a conversation format where we group each of the conversations together. A conversation meaning that it can either be to or from.
An example of what we need this to data to look like is the following format:
{
"result":[
{
"id":"54bf1dc6c65b030c00faec0d",
"name":"Jerry Jones",
"messages":[
{
"text" : "A message to John",
"created" : ISODate("2015-01-29T23:50:10.488Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
{
"text" : "Another message to John",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin fowler"
},
}
]
},
{
"id":"54bf1e80eb5bf8800b0f5a8d",
"name":"John Smith",
"messages":[
{
"text" : "Just another message to Jerry",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Jerry Jones"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
{
"text" : "Message to Martin Fowler",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Martin Fowler"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Jerry Jones"
},
}
]
}
]
}
NOTE This query is always made in the context of a current user which is why on each of the conversations, we have an _id and a name which represents the other user in the conversation. For the example above, the current user would be Martin Fowler
We have tried several different ways of accomplishing this, but keep running into issues. Id rather turn to the Mongo/Node community in order to see how it can be done correctly. We are using mongoose with Node if that helps at all...
The initial query implementation that we have currently is the following:
Message.find().or([{'from.id':req.user.id},{'to.id':req.user.id}]).exec(function(err,messages){
//NEED TO IMPLEMENT THIS HERE CORRECTLY
});
NOTE that the req.user.id is the id of the current user
This solution is a slight modification of my previous solution to a similar kind of problem here.
The documents in question have member names in inconsistent cases. Martin Folwer should be Martin Fowler throughout the app/database, and not Martin fowler. (Note the small f). You need to make this change to your documents.
$group messages together, based on the to and from field.
construct a group key - "message_between", with the value being a
$concat result of the values in to and from fields.
Messages from Martin Fowler to Jerry Jones and Jerry Jones to
Martin Fowler should be treated under a single group.To achieve
that, we make the result contain the name coming last
alphabetically, first. So our key for all the Messages from Martin
Fowler to Jerry Jones and Jerry Jones to Martin Fowler would be
Martin Fowler and Jerry Jones.
Code:
Model.aggregate(
//match all those records which involve the user.
{$match:{$or:[{"to.name":req.user.id},
{"from.name":req.user.id}]}},
{$group:{"_id":{
"message_between":{
$cond:[
{
$gt:[
{$substr:["$to.name",0,1]},
{$substr:["$from.name",0,1]}]
},
{$concat:["$to.name"," and ","$from.name"]},
{$concat:["$from.name"," and ","$to.name"]}
]
},"name":{$cond:[{$eq:["$to.name",
req.user.id]},
"$from.name",
"$to.name"]}
},"messages":{$push:"$$ROOT"}
}
},
{$project:{"_id":0,"name":"$_id.name","messages":1}}
,function(err,resp){
// handle response.
})
o/p:
{
"messages" : [
{
"_id" : ObjectId("54d1d819b62f332e93fbb906"),
"text" : "Just another message to Jerry",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Jerry Jones"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
}
},
{
"_id" : ObjectId("54d1d819b62f332e93fbb907"),
"text" : "Message to Martin Fowler",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Martin Fowler"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Jerry Jones"
}
}
],
"name" : "Jerry Jones"
}
{
"messages" : [
{
"_id" : ObjectId("54d1d819b62f332e93fbb904"),
"text" : "A message to John",
"created" : ISODate("2015-01-29T23:50:10.488Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
}
},
{
"_id" : ObjectId("54d1d819b62f332e93fbb905"),
"text" : "Another message to John",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
}
}
],
"name" : "John Smith"
}
I tried to create a mongo request for you, but i'm not sure it's relevant...
I can generate almost exactly the same format as you need in one request:
db.messages.aggregate([{$match:{$or:[{"from.id":ObjectId("54bf1dc6c65b030c00faec0d")},{"to.id":ObjectId("54bf1dc6c65b030c00faec0d")}]}},{$group:{_id: ObjectId("54bf1dc6c65b030c00faec0d"), messages:{$push: "$$ROOT"}}}]);
The probleme is, you still need to specify the id, i'm not sure it's what you need.
Using this I get the following result:
{
"_id": ObjectId("54bf1dc6c65b030c00faec0d"),
"messages": [
{
"_id": ObjectId("54d1b9f02cd45cae7e453633"),
"text": "A message to John",
"created": ISODate("2015-01-29T23:50:10.488Z"),
"to": {
"id": ObjectId("54bf1dc6c65b030c00faec0d"),
"name": "John Smith"
},
"from": {
"id": ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name": "Martin Fowler"
}
},
{
"_id": ObjectId("54d1ba052cd45cae7e453634"),
"text": "Another message to John",
"created": ISODate("2015-01-30T00:37:38.106Z"),
"to": {
"id": ObjectId("54bf1dc6c65b030c00faec0d"),
"name": "John Smith"
},
"from": {
"id": ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name": "Martin fowler"
}
}
]
}
I'm not using mongoose so I can't help you with this part, but with "mongodb" module, this query can be used directly, so it should be possible with mongoose too.