MongoDB $ne Explanation - mongodb

The official MongoDB api wrote very little about $ne
http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24ne
So when I encountered something like
db.papers.update({"authors cited" : {"$ne" : "Richie"}},
... {$push : {"authors cited" : "Richie"}})
I have no choice but to become utterly confused. Can someone please explain it to me?

This would add "Richie" to the list of authors cited for a paper that does not already have "Richie" as an author.
An alternative would be to use $addToSet.
But then how would I know whether {"authors cited" : {"$ne" : "Richie"}} means the elements in the list corresponding to "author cited", vs the value corresponding to "author cited"?
That is a bit confusing. Generally (I am sure there are exceptions, but those should be documented), all selectors target the individual values for multi-values fields. In Mongo this is called "multikeys" .
Note that this led me to assume initially that your query would target all papers that have at least one author who is not Richie. Then I checked and this turned out to be wrong. +1 for your question, because this really needs to be documented better.

Related

Creating a filter in mongo-go-driver for .FindOne

I'm trying to check a collection to see if there is at least one documents that match a specific set of values.
I've tried reading the documentation at https://github.com/mongodb/mongo-go-driver#usage, but I can't seem to find much help there. I'm pretty new to MongoDB & Go, I believe that this is more a problem of my lack of experience.
Here is a sample query from Studio 3T that I'm trying to run with mongo-go-driver:
db.getCollection("events").find(
{
"event.eventType" : "OSR",
"context.vehicleId" : NumberInt(919514),
"ts" : {
"$gte" : ISODate("2019-06-21T21:38:43.022+0000")
}
}
).limit(1);
It seems that the context.FindOne method will do what I want (and eliminating the need for the .limit(1)). I thought that it would be straight forward to "port" this to Go and the mongo-go-driver.
I can sort of make this work, for example I have the following which will find me all the OSR:
var query = &bson.D{
{"event.eventType", "OSR"},
}
result := bson.D{}
e := collection.FindOne(context.TODO(), query).Decode(&result)
This will return me one document. Now, if I want to include the vehicleId value, and I update the query to:
var query = &bson.D{
{"event.eventType", "OSR"},
{"context.vehicleId", 919514},
}
No documents are returned. I haven't bother to expand query to include the ts field yet.
I would expect at to still have at least one document returned, but nothing is showing up. Does anybody have some tips, suggestions or guidance on what I'm doing wrong (or perhaps how I can do this better)?
Not quite sure, but have you tried with bson.M instead of bson.D?
It seems like it's working for me at least.
query := &bson.M{
"event.eventType": "OSR",
"context.vehicleId": 919514,
}
Please refer to the docs for more information.
Also, like #owlwalks said, are you sure, you're in the right collection?

Mongo query with regex fails when backslash\newline is there in a field

Hi I have a field in a user collection called "Address".User saving their address from a textarea in my application. mongodb convert it to new line like following.
{
"_id": ObjectId("56a9ba0ffbe0856d4f8b456d"),
"address": "HOUSE NO. 3157,\r\nSECTOR 50-D",
"pincode": "",
},
{
"_id": ObjectId("56a9ba0ffbe0856d4f8b456d"),
"address": "HOUSE NO. 3257,\r\nSECTOR 50-C",
"pincode": "",
}
So now When I am running a search query on the basis of "address".Like following:
guardianAdd = $dm->getRepository('EduStudentBundle:GuardianAddress')->findBy(array(
'address' => new \MongoRegex('/.*' .$data['address'] . '.*/i'),
'isDelete' => false
));
echo count($guardianAdd);die;
it does not give any result. My Searchi key word is : "HOUSE NO.3157 SECTOR 50-D".
However if I am searching using like: HOUSE NO. 3157 its giving correct result.
Please advice how to fix this.Thanks in advance
First of all, trailing .* are redundant. regexps /.*aaa.*/ and /aaa/ are identical and match the same pattern.
Second, you probably need to use multiline modifier /pattern/im
Finally, it is not quite clear what you want to fix. The best think you can do is to provide some basic explanation of regex syntax in the search form, so users can search properly, e.g. HOUSE NO.*3157.*SECTOR 50-D to get best results.
You can make some bold assumptions and build the pattern with something like
$pattern = implode('\W+',preg_split('/\W+/', $data['address']))
which will give you a regexp HOUSE\W+NO\W+3157\W+SECTOR\W+50\W+D for different kind of HOUSE NO.3157 SECTOR 50-D requests, but it will cut all the regex flexibility available with bare input, and eventually will result with unexpected response anyway. You can follow this slippery slope and end up with your own query DSL to compile to regex, but I doubt it can be any better or more convenient than pure regex. It will be more error prone for sure.
Asking right question to get right answers is true not only on SO, but also in your application. Unfortunately there is no general solution to search for something that people have in mind, but fail to ask. I believe that in your particular case best code is no code.

ElasticSearch - filter terms for autocomplete

I would like for an autocomplete to get the terms starting with some specific characters.However, the terms returned do not begin with the specified text ("wer" in this case), and more than that, no matter what the prefix content is, they are always the same. The query I am using now is:
{"facets":
{"count":
{"terms":
{"field":"content"},
"facet_filter":
{"prefix":{"content":"wer"}}
}
},
"size":0
}
I am wondering what am I missing or doing wrong. Any help much appreciated. Thanks!
Perhaps you miss a "query" entry after the facet_filter.
If this does not help try regex pattern for facets, but be aware that facets will be removed in future updates of elasticsearch.
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-terms-facet.html#_regex_patterns

mongodb - i cannot update with $pushAll and simple assignment at the same time

the following fails:
db.test.update({_id:102},{$pushAll:{our_days:["sat","thurs","frid"]}, country:"XYZ"}, {upsert:true})
error message: "Invalid modifier specified: country"
The correct way seems to be:
db.test.update({_id:102},{$pushAll:{our_days:["sat","thurs","frid"]}, $set:{country:"XYZ"}}, {upsert:true})
So is it the case that I cannot mix modifiers like "$pushAll" with simple assignments like field:value, in the same update document? Instead I have to use the $set modifier for simple assignments?
Is there anything in the docs that describes this behaviour?
This happens because db.test.update({_id : 1}, {country : 1}) will just change the whole document to country = 1 and thus removing everything else.
So most probably mongo being smart tells you: You want to update specific element and at the same time to remove everything (and that element as well) to substitute it with country = 1. Most probably this is not what you want. So I would rather rise an error.
Regarding the documentation - I think that the best way is to reread mongodb update.

Mongodb - query with '$or' gives no results

There is extremely weird thing happening on my database. I have a query:
db.Tag.find({"word":"foo"})
this thing matches one object. it's nice.
Now, there's second query
db.Tag.find({$or: [{"word":"foo"}]})
and the second one does not give any results.
There's some kind of magic I obviously don't understand :( What is wrong in second query?
in theory, $or requires two or more parameters, so I can fake it with:
db.Tag.find({$or: [{"word":"foo"},{"word":"foo"}]})
but still, no results.
Your second query is perfectly fine, and it should work. Though the docs says, that $or performs logical operation on array of two or more expression, but it would work for single expression also.
Here's a sample that you can see, and try out, to get it to work: -
> db.col.insert({"foo": "Rohit"})
> db.col.insert({"foo": "Aman", "bar": "Rohit"})
>
> db.col.find({"foo": "Rohit"})
{ "_id" : ObjectId("50ed6bb1a401d9b4576417f7"), "foo" : "Rohit" }
> db.col.find({$or: [{"foo": "Rohit"}]})
{ "_id" : ObjectId("50ed6bb1a401d9b4576417f7"), "foo" : "Rohit" }
So, as you can see, both your query when used for my collection works fine. So, there is certainly something wrong somewhere else. Are you sure you have data in your collection?
Okaay, server admin installed mongodb from debian repo. Debian repo had 1.4.4 version of mongodb, aandd looks like $or is simply not yet supported out there :P