Im a beginner in MongoDB2.6. I'm exploring "Text" indexing in Mongodb.
My Collection has below documents.
{ "_id" : ObjectId("54961bfa913a9f096e9390a3"), "Comments" : "David went to Park today" }
{ "_id" : ObjectId("54961e5b913a9f096e9390a7"), "Comments" : "David went to Park today", "Toldby" : "How are You" }
{ "_id" : ObjectId("54961be4913a9f096e9390a1"), "Comments" : "Park in Irvine are beautiful"}
I have created an "Text" Index on Comments Column.
db.textcollection.find({$text:{$search:"Park"}}) --> This Command returns all three documents
But when i try to replace "Park" with "in" i get no output, should it return the last document for me? . Please correct me if my understanding is wrong.
The most common words of the text index's configured language (english, by default) are known as "stop words" and are excluded from the index. Examples from your strings are words like "to", "in", and "are". As such, you won't get any results if you search on those words.
If you actually need those words included, then you can set the text index's language to "none" which disables all the smarts of stop words and word stemming.
Related
Here is the model 'Class' model for which I have created the "text" index for 'keywords','lifeArea',''type'.
Structure of the model:
{
"_id" : ObjectId("558cf6e3387419850d892712"),
"keywords" : "rama,seetha",
"lifeArea" : [
"Emotional Wellness"
],
"type" : "Pre Recorded Class",
"description" : "ram description",
"synopsis" : "ram syn",
"name" : "ram demo",
"__v" : 0
}
db.Class.getIndexes()
// displaying index
{
"v" : 1,
"key" : {
"_fts" : "text",
"_ftsx" : 1
},
"name" : "classIndex",
"ns" : "innrme.classes",
"weights" : {
"keywords" : 1,
"lifeArea" : 1,
"type" : 1
},
"default_language" : "english",
"language_override" : "language",
"textIndexVersion" : 2
}
I want to do a text search on the fields mentioned above. I tried the following query.
db.classes.find({$or:[{keywords: { $text: { $search: "rama abc" } } }, {type: {$text: { $search: "class" }}}],score: {$meta: 'textScore'}});
But it did not work and I got the follwing error
Error: error: {
"$err" : "Can't canonicalize query: BadValue unknown operator: $text",
"code" : 17287
}
Please help me to get the correct query.
Please correct/educate me if I am wrong in asking the question or in explaining the problem
That actual error suggests your mongodb is a version less than 2.6 ( so no text search in that way ). But you cannot do that anyway for two reasons.
An $or expression can only have one special index expression, being either "text" or "geospatial" in the arguments.
You are expecting text searches on "two" different fields and you can only have one text index per collection. However that single index can be spread over several fields in the document. But you cannot ask different search terms for different fields.
Documentation quote:
You cannot combine the $text expression, which requires a special text index, with a query operator that requires a different type of special index. For example you cannot combine $text expression with the $near operator.
And it should also say "You cannot use $or with a $text expression or the $near operator where either are used in more than one condition." But that little piece of information is missing, but you still cannot do it.
Your syntax is generally not correct, but even with the correct syntax in a supported version of MongoDB you would get an error trying to use $or like this:
Error: error: {
"$err" : "Can't canonicalize query: BadValue Too many text expressions",
"code" : 17287
}
So to resolve this you need:
To have a MongoDB server version of 2.6 or greater that supports the $text syntax ( or live with command forms )
To live with indexing over multiple fields and using a single index.
To execute "separate queries" in place of your "or" conditions and "combine" the results in your client API interface.
That is the only way you get "or" conditions like this with MongoDB text search.
First of all I don't think you can use $text in that manner, you need first to create a text index on the collection then you can use it but without specifying any field because it works on indexes not fields.
Please check here: http://docs.mongodb.org/manual/administration/indexes-text/
For example: I have some arrays without the word "cheese" and some with "cheese" and others with "extra cheese." $regex was a command I found that could search for particular word, so I could used that, I think, to exclude some values.
Here is one of my objects:
{
"_id" : ObjectId("5ebf0cd0b14985ef2b48af46"),
"meat" : "chicken",
"cheese" : false,
"toppings" : [
"mac and cheese",
"biscuit"
]
}
Cheese is included in "mac and cheese" and should not be returned. I used "db.burger.find({}, {meat:1, toppings:1})" but it still returns the value "mac and cheese".
Thanks in advance.
I am using mongodb, I am stucked on a issue :
Data is :
{
"_id" : ObjectId("5a956e0b78d363d37f6a2ec4"),
"fieldType" : "Enter Source",
"value" : "Delhi",
"catgeory" : "Generic",
"synonym" : [
"origin name or code",
"from",
"enter source",
"from where",
"fro wher"
]
}
When I use this query
db.getCollection("Rules_DefaultValue").find(
{
"synonym" : "from where"
});
I got correct result as expected
But when I use this query
db.getCollection("Rules_DefaultValue").find(
{
"$text" : {
"$search" : "where"
}
});
I didn't got any result , So I changed it again
db.getCollection("Rules_DefaultValue").find(
{
"$text" : {
"$search" : "wher"
}
});
and this time it worked.
So I came to a conclusion that "where" is reserve keyword and I can't use it as it is. So I tried with escape char :
"$search" : "\"where\""
but again I did'nt got the result.
same thing is happening with
and , from , *
Please help me on this , How can I make query with these words.
Words like where and from are considered as stopwords in MongoDB. It means that when you create a text index those words are wiped out from the index since they appear very frequently in English while the point of FTS is to index some words that allow you to easily find the document you're looking for. To fix that you can create your text index specifying language to none, try:
db.getCollection("Rules_DefaultValue").createIndex(
{ synonym : "text" },
{ default_language: "none" }
)
Then your query should return the document mentioned in your post.
I have mongo documents as follows,
{
"_id" : ObjectId("5b5ff3ec6df1fc21dc206d12"),
"activityName" : "How sensor",
"timeZone" : "+05.30",
"venue" : "130 E San Fernando St #154, San Jose, CA 95112, USA",
"activityState" : "Active",
"activityType" : "campaign",
"commentTheme" : "59c26fb3fd9a8e79242fe210",
"commentEnabled" : false,
"startTimeStamp" : 1532602800000.0,
"endTimeStamp" : 2164186800000.0
}
And there is a text index created on filed activityName as follows,
`db.ActivityDetails.createIndex( { 'activityName':'text' } );`
But for the text search keyword how it doesn't output given document as results. Does anyone knows a possible reason for this behaviour. My query is as follows,
db.getCollection('ActivityDetails').find({ $text: { $search: "how" } })
but for the word sensor, it gives the correct results. Appreciate any help
'how' is a stop word in English It is ignored in text index and can't be searched.
You can experiment with {default_language: 'none'} which will not use any stop words, but it won't use steming either, so sensor won't match sensors.
This my code:
db.test.find() {
"_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
"title" : "Sir",
"name" : {
"_id" : ObjectId("4d3ed089fb60ab534684b7ff"),
"first_name" : "Farid"
},
"addresses" : [
{
"city" : "Baku",
"country" : "Azerbaijan"
},{
"city" : "Susha",
"country" : "Azerbaijan"
},{
"city" : "Istanbul",
"country" : "Turkey"
}
]
}
I want get output only all city. Or I want get output only all country. How can i do it?
I'm not 100% about your code example, because if your 'find' by ID there's no need to search by anything else... but I wonder whether the following can help:
db.test.insert({name:'farid', addresses:[
{"city":"Baku", "country":"Azerbaijan"},
{"city":"Susha", "country":"Azerbaijan"},
{"city" : "Istanbul","country" : "Turkey"}
]});
db.test.insert({name:'elena', addresses:[
{"city" : "Ankara","country" : "Turkey"},
{"city":"Baku", "country":"Azerbaijan"}
]});
Then the following will show all countries:
db.test.aggregate(
{$unwind: "$addresses"},
{$group: {_id:"$country", countries:{$addToSet:"$addresses.country"}}}
);
result will be
{ "result" : [
{ "_id" : null,
"countries" : [ "Turkey", "Azerbaijan"]
}
],
"ok" : 1
}
Maybe there are other ways, but that's one I know.
With 'cities' you might want to take more care (because I know cities with the same name in different countries...).
Based on your question, there may be two underlying issues here:
First, it looks like you are trying to query a Collection called "test". Often times, "test" is the name of an actual database you are using. My concern, then, is that you are trying to query the database "test" to find any collections that have the key "city" or "country" on any of the internal documents. If this is the case, what you actually need to do is identify all of the collections in your database, and search them individually to see if any of these collections contain documents that include the keys you are looking for.
(For more information on how the db.collection.find() method works, check the MongoDB documentation here: http://docs.mongodb.org/manual/reference/method/db.collection.find/#db.collection.find)
Second, if this is actually what you are trying to do, all you need to for each collection is define a query that only returns the key of the document you are looking for. If you get more than 0 results from the query, you know documents have the "city" key. If they don't return results, you can ignore these collections. One caveat here is if data about "city" is in embedded documents within a collection. If this is the case, you may actually need to have some idea of which embedded documents may contain the key you are looking for.