MongoDB Match 2 criteria - mongodb

Given the Set in my Image Example,
Is it possible to retrieve by ID and if 'element is in the array'?
As you can see I can find all the records with the element in the array, but as I drill down and find the one by ID as well, it throws an Error, I suspect my syntax is wrong
here is a link to my chat on SO https://chat.stackoverflow.com/transcript/message/5006697#5006697
Thanks in Advance
CAM

You basically have the $in in the projection field (what you want to return) because you closed out the criteria document (what you want to find) early. Try this:
db.users.find( {'_id':1, 'companies-visited': { $in:["stocktwits"]}})

Related

Basic MongoDb Retrieval

I have two "documents" that I inserted into my MongoDB database.
questionsList.insert({question: "When was the War of 1812", answer: "1812", answers: ["1811", "1812", "1813", "1814"]})
questionsList.insert({question: "What year did the US land on the moon?", answer: "1969", answers: ["1969", "1970", "1971", "1972"]})
I simply want to access the answer value from the second document. I have been reading the documentation and it doesn't seem to work. I can retrieve the answer value from the first document without issue: var str = questionsList.findOne({}, {question: 1}).answer; I presume that since I am using findOne I can't find any other matches. The problem is that I can't seem to pull up the second document and its corresponding answer. I have tried many different ways:
questionList.find({}, {answer: 1})
questionList.find({answer: 1})
questionList.find({}).answer
My ultimate goal is to compare this answer with one of the click one answers from choices What am I missing?
If I understood your scenario correctly, you are trying to retrieve a document based on the document index (Which is not the right thing to do, since MongoDB does not store documents in specific order).
The reason why findOne works is, because it just returns the first document in your collection.
What I believe you should do instead is retrieve the answer based on the question. Something like:
db.questionsList.find({question:"What year did the US land on the moon?"},{answer:1})
Update:
In the case of meteor.js
questionsList.find({question:"What year did the US land on the moon?"}).fetch()[0].answer
The reason whey we need to give [0] is fetch() returns an array of objects. (Since there can be multiple documents with same key)
The final step is:
questionsList.find({"question": "You are human"}, {"answer": 1}).fetch()[0].answer
We are treating it as any other object (i.e. the first within a list of objects and using dot-notation)

Meteor Mongodb first object array not selectable with dot notation

I have tried and tried on Meteor and on Robomongo (Mongodb) to select objects with dot notation.
I would like to be able to filter team.0.wageringStats.wageringStraightSpread objects (sometimes subjects can be fields or arrays - thats another issue)
In the first image I can select team.wageringStats.wageringStraightSpread and get back all the subOjects of team (team has siblings not shown in images)
The second image I tried team.0.wageringStats.wageringStraightSpread and I get no fields.
Lastly i tried team.[0].wageringStats.wageringStraightSpread and
team[0].wageringStats.wageringStraightSpread and get the same result : 0 fields
I am at a loss and would like some help. Thank you
I am not sure what you are trying to do now? Because in your first command, you already have a list of team that match your criteria and then, put it into the loop of meteor to process. Why do you need to find only the first one ? By the way, in order to select the nth of the result set in mongodb, you will need something like skip and limit
db.collections.find({'team.wageringStats.wageringStraightSpread':1}).limit(1).skip(0)
(in skip, you need to pass the offset you need to reach to)
Also, if you only care about the first one, findOne is the one you need to do the query
db.collections.findOne({'team.wageringStats.wageringStraightSpread':1})
Be aware that the syntax of mongodb and meteor for querying is a bit different

meteor, find whether user exists in mongodb document array or not?

This is my meteor code to search whether user exist in the array or not
var u_exist=Polls_Coll.findOne( {option1:{$elemMatch:{ids:"xxx"}}} );
My question is, How to know whether the statement returning something or not(user exist or not)
$elemMatch will return only where one of the conditions supplied actually finds a match in the array. So if you don't get a document back then there was no match.
Also findOne is a single document. Modifiers such as .count() will not work on that. If you have more documents to be expected use find intstead. Also findOne not not make much sense without applying a unique identifier such as _id in the query. Without that you are almost certainly not getting what you want.
While useful for your purpose, findOne is not a good match with the $elemMatch operator. The reasoning is you can possibly get multiple results of the same document having the same set of array elements that matched the condition that you gave.
Buyer beware.

MongoDB $in not only one result in case of repeated elements

I need to get the users whose ids are contained in an array. For this i'm using the $in operator, however being this inside an aggregate operation, i'd like to get back a specific user all the time it's id is present in the array, not just one. For example:
The ids array is A=[a,b,c,b] and U(x) is user with id x
with users.find({_id:{$in:A}}) i get these users as result: U(a),U(b),U(c)
instead i'd like to get back the result: U(a),U(b),U(c),U(b)
so get the user back every time it's id appears.
I understand that $in is working as expected but does anyone have an idea on how can i achieve this?
Thanks
This isn't possible using a MongoDB query.
MongoDB's query engine iterates over the documents in a collection (or over an index if there's a useful one) and returns to you any documents that match your query, in the order it finds them. Whether b appears once, twice, or a hundred times in your query makes no difference: the document with _id of b matches the query and is returned once, when MongoDB finds it.
You can do a post-processing step in your programming language to repeat documents as many times as you want.

In Mongodb, how to retrieve the subset of an object that matches a condition?

What I'm trying to do:
Filter a field of a collection that matches a given condition. Instead of returning every item in the field (which is an array of items), I only want to see matched items.
Similar to
select items from test where items.histPrices=[10,12]
It is also similar to what's found on the mongodb website here: http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields
Here's what I have been trying:
db.test.save({"name":"record", "items":[{"histPrices":[10,12],"name":"stuff"}]})
db.test.save({"name":"record", "items":[{"histPrices":[10,12],"name":"stuff"},
{"histPrices":[12,13],"name":"stuff"},{"histPrices":[11,14],"name":"stuff"}]})
db.test.find({},{"name":1,"items.histPrices":[10, 12]})
It will return all the objects that have a match for items.histPrices:[10,12], including ALL of the items in items[]. But I don't want the ones that don't match the condition.
From the comments left on Mongodb two years ago, the solution to get only the items with that histPrices[10,12] is to do it with javascript code, namely, loop through the result set and filter out the other items.
I wonder if there's a way to do that with just the query.
Your find query is wrong
db.test.find({},{"name":1,"items.histPrices":[10, 12]})
Your condition statement should be in the first part of the find statement.In your query {} means fetch all documents similar to this sql
select items from test (no where clause)
you have to change your mongodb find to
db.test.find({"items.histPrices":[10, 12]},{"name":1})
make it work
since your items is an array and if you wanted to return only the matching sub item, you have to use positional operator
db.test.find({"items.histPrices":[10, 12]},{"name":1,'items.$':1})
When working with arrays Embedded to the Document, the best approach is the one suggested by Chien-Wei Huang.
I would just add another aggregation, with the $group (in cases the document is very long, you may not want to retrieve all its content, only the array elements) Operator.
Now the command would look like:
db.test.aggregate({$match:{name:"record"}},
{$unwind:"$items"},
{$match {"items.histPrices":[10, 12]}},
{$group: {_id: "$_id",items: {$push: "$items"}}});)
If you are interested to return only one element from the array in each collection, then you should use projection instead
The same kind of issue solved here:
MongoDB Retrieve a subset of an array in a collection by specifying two fields which should match
db.test.aggregate({$unwind:"$items"}, {$match:{"items.histPrices":[10, 12]}})
But I don't know whether the performance would be OK. You have to verify it with your data.
The usage of $unwind
If you want add some filter condition like name="record", just add another $march at first, ex:
db.test.aggregate({$match:{name:"record"}}, {$unwind:"$items"}, {$match:{"items.histPrices":[10, 12]}})
https://jira.mongodb.org/browse/SERVER-828
Get particular element from mongoDB array
MongoDB query to retrieve one array value by a value in the array