In my cloudant database I have objects like these. I'd like to query for objects that based on properties in a nested array.
In the example below, how to I query for all objects where there is a vote with userId=="user1"? The query should return both objects. When I search for userId "user2" it should return the first one as the second object only has vote from user1 and user4.
{
"_id": "1",
"votes": [
{
"userId": "user1",
"comment": ""
},
{
"userId": "user2",
"comment": ""
},
{
"userId": "user3",
"comment": ""
}
]
}
{
"_id": "2",
"votes": [
{
"userId": "user1",
"comment": ""
},
{
"userId": "user4",
"comment": ""
}
]
}
This view will return a list of all votes (where a vote is userId and _id) sorted by userId, to only get user1 use ?key="user1"
function(doc) {
for(i in doc.votes)
emit(doc.votes[i].userId, doc._id);
}
/dbName/_design/foo/_view/bar?key="user1"
{"total_rows":5,"offset":0,"rows":[
{"id":"1","key":"user1","value":"1"},
{"id":"2","key":"user1","value":"2"}
]}
Related
{
"name": "user2",
"avatar": 1,
"email": "example#gmail.com",
"categories": [
{
"cname": "Category 1",
"list": [
{
"status": "pending",
"name": "List Item 1"
},
{
"status": "pending",
"name": "List Item 2"
}
]
}
]
}
I want to update "categories.list.status" = "pending" to "completed". How can I do it? I tried using positional operator($) but it is giving error too many positional operator.
If you are using Mongoose (as your tags suggest), you can just update the value in the document object and then save it
document.list[0].status = "completed";
document.save();
I tried this. It worked.
document.updateOne({_id: id}, {
{
$set: {
"categories.$[].list.$[ele].status" : status
}
},
{
arrayFilters: [{"ele.name" : name}]
}
}
There is a sub-field called 'name' in MongoDB Collection (User):
[
{
"teacher": {
"name": "Alex",
"email": "alex#domain.com"
},
"waiter": {
"name": "Feliks",
"email": "feliks#domain.com"
},
"pilot": [
{
"name": "Sam",
"email": "sam#domain.com"
},
{
"name": "alice",
"email": "alice#domain.com"
}
],
},
{
"teacher": {
"name": "max",
"email": "max#domain.com"
},
"waiter": {
"name": "Sam",
"email": "sam#domain.com"
},
"pilot": [
{
"name": "richard",
"email": "richard#domain.com"
},
{
"name": "alice",
"email": "alice#domain.com"
}
],
}
]
How can I find data based on the field 'name'. For example, when I'm looking for 'Sam', it should return me the all documents since 'Sam' is in "waiter" and "pilot" in first and second documents respectively.
I cannot do something like:
User.find({"teacher.name": "Sam", "waiter.name": "Sam", "pilot.name": "Sam" })
This will return me nothing as it is an AND logic. What I need is an OR logic.
You can use the $or operator.
So the query should look like this:
User.find({ $or: [
{ "teacher.name": "Sam" },
{ "waiter.name": "Sam" },
{ "pilot.name": "Sam" }
]
});
Read here for me details.
I'll explain: I have this function
function (doc) {
if(doc.MovieId == "1721")
emit(doc.Rating, 1);
}
but it return me some document that are not relevant (for example they haven't the Rating field). My document _id is composed of partitionName:id, so I thought to do if(doc.MovieId == "1721" && doc._id.contains("ratings"){...} but it doesn't work.
Is there a way to do this?
-----EDIT 1-----
The docs in the circle are not relevant.
Do you need the schema of the JSON document?
-----EDIT 2-----
the following documents are NOT RELEVANT
1.
{
"_id": "movies : 1721",
"_rev": "1-d7e0e3c8152d6978073d280e0aef7457",
"MovieId": "1721",
"Title": "Titanic (1997)",
"Genres": [
"Drama",
"Romance"
]
}
2.
{
"_id": "tags : 1490",
"_rev": "1-14c20c9cfb3ee1964a298777f80333d5",
"MovieId": "1721",
"UserId": "474",
"Tag": "shipwreck",
"Timestamp": "1138031879"
}
3.
{
"_id": "tags : 2791",
"_rev": "1-e4d6c9573fcdae726a69d5fc6255de27",
"MovieId": "1721",
"UserId": "537",
"Tag": "romance",
"Timestamp": "1424141922"
}
documets like this are RELEVANT:
{
"_id": "ratings : 31662",
"_rev": "1-446665286337faaf51e23e40b527ec2d",
"MovieId": "1721",
"UserId": "219",
"Rating": "0.5",
"Timestamp": "1214043346"
}
Following view should just emit documents whose _id starts with "ratings :":
function (doc) {
var id_prefix = "ratings :";
if(doc._id.substr(0, id_prefix.length) === id_prefix && doc.MovieId == "1721")
emit(doc.Rating, 1);
}
I have a collection which contains some documents as follows,
{
"transactionId": 3432423,
"reviews": [
{
"fromUser": {
"userId": "5236aa1acd6e"
},
"toUser": {
"userId": "0ec8db9544cc"
},
"rating": 4.3,
"comment": ""
},
{
"toUser": {
"userId": "5236aa1acd6e",
"email": "yourlife#gmail.com",
"firstName": "your",
"lastName": "life"
},
"fromUser": {
"userId": "0ec8db9544cc",
"email": "mylife#gmail.com",
"firstName": "my",
"lastName": "life"
},
"rating": 4.3,
"comment": ""
}
]
}
i need to check if subdocument reviews present inside the document. i have used this query,
db.getCollection('_testCollection').find({ "$elemMatch": { "reviews": { "$exists": false } }})
it throws an error saying,
"errmsg" : "unknown top level operator: $elemMatch",
Neither $elemMatch or $exists is what you want to use to determine if reviews is an empty array.
Instead, either compare against []:
db.test.find({reviews: []})
Or use the $size operator:
db.test.find({reviews: {$size: 0}})
From the Docs :-
The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.
db.getCollection('_testCollection').find({ "reviews": {"$elemMatch" : { "$exists": false } }})
$exists :- true or false // depend on requirement
Thanks
Given a collection of objects held within CouchDB that look like this:
{
"_id": "-5739365454",
"_rev": "1-d55b2651b214113bab0b4c18a401eaef",
"userId": "mike",
"remoteAddr": "77.102.112.205"
}
{
"_id": "-573936626",
"_rev": "1-778bbf1c0e5cfe8bbd83dbe618e8b549",
"userId": "mike",
"remoteAddr": "77.102.112.205"
}
...
{
"_id": "-573954545",
"_rev": "1-4350856f40c091156f8bb984a5559ebd",
"userId": "jeff",
"remoteAddr": "77.102.112.205"
}
I wish to create an output view that give me a set of results that looks something like the following (pseudo output - not syntactically valid):
userId count
mike 2
jeff 1
...
So, one 'row'/element would exist in the output for each distinct userId in the DB, along with the number of times that userId exists in the DB.
So far I have the following:
{
"_id": "_design/myObj",
"_rev": "4-cd468634f4fb6bef500753fedcb35e27",
"views": {
"by_userId": {
"map": "function(doc) { if (doc.userId) { emit (doc.userId, doc._id)} }",
"reduce": "_stats"
}
},
"language": "javascript"
}
... but this is not working as required. Any assistance gratefully received!
You could try use _count built-in function. For instance:
`
{
"_id": "_design/myObj",
"_rev": "4-cd468634f4fb6bef500753fedcb35e27",
"views": {
"by_userId": {
"map": "function(doc) { if (doc.userId) { emit (doc.userId, null)} }",
"reduce": "_count"
}
},
"language": "javascript"
}`