Mongo: select only one field from the nested object - mongodb

In mongo I store object that have field "titleComposite". This field contains array of title object, like this:
"titleComposite": [
"0": {
"titleType": "01",
"titleText": "Test cover uploading"
}
]
I'm perfoming query and I would like to receive only "titleText" value for the returned values. Here is an example of my query:
db.onix_feed.find({"addedBy":201, "mediaFileComposite":{$exists:false}}, {"isbn13":1,"titleComposite.titleText":1})
In the results I see values like
{
"_id" : ObjectId("559ab286fa4634f309826385"),
"titleComposite" : [ { "titleText" : "The Nonprofit World" } ],
"isbn13" : "9781565495296"
}
Is there any way to get rid of "titleComposite" wrapper object and receive only titleText? For example, take titleText of the first element only?
Would appreciate any help

You can mongodb aggregation to achieve your expected result. Re-arrange your query as following...
db.onix_feed.aggregate([
{
$match: {
$and: [
{"addedBy":201},
{"mediaFileComposite":{$exists:false}}
]
}
},
{
$project : { titleText: "$titleComposite.titleText",
"isbn13" : 1 }
}
])

Related

Pymongo - Query mongdb for first array elemnet by query of list of values

Given collection:
{
"_id" : "1.1000038",
"recomendation" : [
"1.6739718"
]
}
/* 2 */
{
"_id" : "1.1000069",
"recomendation" : [
"1.9185509",
"1.9051998",
"1.9034279",
"1.8288046",
"1.8152670",
"1.858775",
"1.6224229",
"1.4591674",
"1.3862464",
"1.3427739",
"1.3080062",
"1.3003608",
"1.1694619",
"1.1634683",
"1.1590664",
"1.1524146",
"1.754599",
"1.700837",
"1.763617"
]
}
I need to query the MongoDB for a list of values and get the first element of the list of values
here is the query by mongo syntax
db.getCollection('similar_articles').find({"_id":{$in:["1.1000069","1.1000038"]}})
I don't want to filter it on the python side because it's can be too big.
I didn't find any documentation on it
desire output:
Pandas DataFrame
_id recom
1.1000038 1.6739718
1.1000069 1.9185509
I don't know pymongo so well, but you need this query:
First $match by _ids into the arreay (this is like the find you have).
And later use $project to create the field recom (you can use "recomendation" to overwrite the existing field) and set the value as the first into the array.
db.collection.aggregate([
{
"$match": { "_id": { "$in": [ "1.1000069", "1.1000038" ] } }
},
{
"$project": { "recom": { "$arrayElemAt": [ "$recomendation", 0 ] } }
}
])
Example here
Looking the doumentation it seems you only need to copy and paste this query.

Query document for record with array value of null

I have a document like this:
{
"_id" : "4mDYgt6gID",
...
"MultipleChoiceQuestions" : [
{
...
"LeadInFile" : null,
...
},
{
...
"LeadInFile" : 'some string',
...
}
],
...
}
How do I query for any documents that have a non-null value in LeadInFile?
I'm trying different things, currently something like this
db.getCollection('QuizTime:Quizzes').find({"MultipleChoiceQuestions": [{ "LeadInFile": { $ne: null}}]});
Is returning 0 records.
The current form of the query is saying:
Find documents where MultipleChoiceQuestions is [{ "LeadInFile": { $ne: null}}]
Try using dot notation; this is used to access elements of an array or fields in an embedded document. For example:
db.getCollection('QuizTime:Quizzes').find({
"MultipleChoiceQuestions.LeadinFile" : { "$ne" : null }
})

Query by two params with $and in mongoose?

I have a user model like this:
user : {
myArmy : {
mySoldiers : [
{
positioned : false,
soldierInfo : {
_id : s99212
}
},
{
positioned : true,
soldierInfo : {
_id : s99112
}
}
]
}
},
user : {
myArmy : {
mySoldiers : [
{
positioned : true,
soldierInfo : {
_id : s99212
}
},
{
positioned : false,
soldierInfo : {
_id : s99112
}
}
]
}
}
...
I have a query that i want to do to return the user(s) who have soldier id s99212 positioned (true): (could be thousands of those, and i need to read and retrieve them all)
This is my faulty query with mongoose:
var soldierId = s99212;
stream = User.find({
$and: [
{'myArmy.mySoldier.positioned': {$ne: null}},
{'myArmy.mySoldier.soldierInfo._id': soldierId}
]
}).lean(true).stream();
Nothing is returned by this query, should there be another way to do this $and stuff?
How exactly am i suppose to use $elemMatch if at all, should it be instead of the find? (If it worth to mention, i want to return the complete user object, not just parts of it...)
Tried this, crashed my app:
stream = User.find({
'$elemMatch': [
{'myArmy.mySoldiers.pos': {$ne: null}},
{'myArmy.mySoldiers.soldierInfo._id': soldierId}
]
}).lean(true).stream();
I know i have a small syntax problem, where is it?
Very simple and well documented. The $elemMatch operator acts as a "query in itself", where it applies "it's conditions" to members of the array specified:
var query = User.find({
"myArmy.mySoldiers": {
"$elemMatch": {
"positioned": { "$ne": null },
"soldierInfo._id": soldierId
}
}
});
Therefore for a document to "match" then the conditions specfied under $elemMatch must be present and valid for the "same" array element. Array on "left", arguments on "right".
Other "dot notation" forms only ever test that the values match "some element" in the array, and not necessarily the same one.

Mongodb: Trying to find all documents with specific subdocument field, why is my query not working?

Here is an example of a document from the collection I am querying
meteor:PRIMARY> db.research.findOne({_id: 'Z2zzA7dx6unkzKiSn'})
{
"_id" : "Z2zzA7dx6unkzKiSn",
"_userId" : "NtE3ANq2b2PbWSEqu",
"collaborators" : [
{
"userId" : "aTPzFad8DdFXxRrX4"
}
],
"name" : "new one",
"pending" : {
"collaborators" : [ ]
}
}
I want to find all documents within this collection with either _userId: 'aTPzFad8DdFXxRrX4' or from the collaborators array, userId: 'aTPzFad8DdFXxRrX4'
So I want to look though the collection and check if the _userId field is 'aTPzFad8DdFXxRrX4'. If not then check the collaborators array on the document and check if there is an object with userId: 'aTPzFad8DdFXxRrX4'.
Here is the query I am trying to use:
db.research.find({$or: [{_userId: 'aTPzFad8DdFXxRrX4'}, {collaborators: {$in: [{userId: 'aTPzFad8DdFXxRrX4'}]}}] })
It does not find the document and gives me a syntax error. What is my issue here? Thanks
The $in operator is basically a simplified version of $or but you really only have one argument here so you should not even need it. Use dot notation instead:
db.research.find({
'$or': [
{ '_userId': 'aTPzFad8DdFXxRrX4'},
{ 'collaborators.userId': 'aTPzFad8DdFXxRrX4'}
]
})
If you need more than one value then use $in:
db.research.find({
'$or': [
{ '_userId': 'aTPzFad8DdFXxRrX4'},
{ 'collaborators.userId': {
'$in': ['aTPzFad8DdFXxRrX4','aTPzFad8DdFXxRrX5']
}}
]
})

mongodb update push sub-subdocument

The question is quite easy. I have the following document in mongoDb:
_id : ObjectId("519e3c14ade67153e9a003a0")
status:1,
name:"name",
details:
{
crm:115,
webs:
[
{ tag:"blog" , url:"http://..."}
],
contacts:
[
{
_id:ObjectId("009e37e1ade67153e9a0039e"),
name:"me",
phones:
[
{ tag:"home", number:"123..." },
{tag:"mobile", number:"123456789"}
]
}
]
}
I am trying to update one fo the phones in the subdocument details.contacts doing this:
db.new.update(
{
_id : ObjectId("519e3c14ade67153e9a003a0"),
"details.contacts._id": ObjectId("009e37e1ade67153e9a0039e"),
"details.contacts.phones.tag":"home"
},
{
$set:
{
"details.contacts.$.phones.$":
{
tag:"home",
number:"965923777"
}
}
})
and finally I get the following error: Cannot apply the positional operator without a corresponding query field containing an array.
There is anyway to update the document in this way or i should send all the phones to update this field?