How to add LIKE parameter in mongodb geoNear command - mongodb

I am searching
db.runCommand({
geoNear: "users",
near:[56,11],
maxDistance:100/6387,
distanceMultiplier:6387,
query: { "city": /^bos/}
})
So here i am trying to get results with distances(priority) & city name that starts with bos
as we make LIKE query call in mysql so
i am not able to get results.
Please tell me how can i do that?

Adding the "query" parameter to the command should give you the results that you are looking for.
One possible reason that your query might not be working is that regular expressions are case-sensitive unless specified as case-insensitive with the 'i' flag.
For example:
> db.places.save({_id:1, city:"CityA", loc:[56.01,11.01]})
> db.places.save({_id:2, city:"CityB", loc:[56.02,11.02]})
> db.places.ensureIndex({loc:"2d"})
> db.runCommand({ geoNear: "places", near:[56,11], maxDistance:1, distanceMultiplier:1, query: { "city": /^city/} })
{
"ns" : "test.places",
"near" : "1100100000111111111100110000110000111111111100110000",
"results" : [ ],
"stats" : {
"time" : 0,
"btreelocs" : 0,
"nscanned" : 2,
"objectsLoaded" : 2,
"avgDistance" : NaN,
"maxDistance" : 0
},
"ok" : 1
}
Nothing is returned. Now the command is rerun, with the case-insensitive flag in the regex part of the query:
> db.runCommand({ geoNear: "places", near:[56,11], maxDistance:1, distanceMultiplier:1, query: { "city": /^city/i} })
{
"ns" : "test.places",
"near" : "1100100000111111111100110000110000111111111100110000",
"results" : [
{
"dis" : 0.014142135623729393,
"obj" : {
"_id" : 1,
"city" : "CityA",
"loc" : [
56.01,
11.01
]
}
},
{
"dis" : 0.02828427124746381,
"obj" : {
"_id" : 2,
"city" : "CityB",
"loc" : [
56.02,
11.02
]
}
}
],
"stats" : {
"time" : 0,
"btreelocs" : 0,
"nscanned" : 2,
"objectsLoaded" : 2,
"avgDistance" : 0.0212132034355966,
"maxDistance" : 0.028292673810819097
},
"ok" : 1
}
>
Both locations are returned. The documentation on using regular expression with Mongo queries may be found in the "Regular Expressions" section of the "Advanced Queries" page:
http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions
Hopefully the above will resolve your issue and allow you to perform the correct query.

Related

mongodb $near query is slow

One mongodb collection
{
"_id" : ObjectId("574bbae4d009b5364abaebe5"),
"cityid" : 406,
"location" : {
"type" : "Point",
"coordinates" : [
118.602355,
24.89083
]
},
"shopid" : "a"
}
with about 50, 000 rows;
and indexes:
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "pingan-test.shop_actinfo_collection_0530"
},
{
"v" : 1,
"key" : {
"location" : "2dsphere"
},
"name" : "location_2dsphere",
"ns" : "pingan-test.shop_actinfo_collection_0530",
"2dsphereIndexVersion" : 3
},
{
"v" : 1,
"key" : {
"shopid" : 1,
"cityid" : 1
},
"name" : "shopid_1_cityid_1",
"ns" : "pingan-test.shop_actinfo_collection_0530"
}
]
I query this collection like:
body = {'cityid': 2, 'location': {'$near': {'$geometry': {'type': 'Point', 'coordinates': [122.0, 31.0]}}}, 'shopid': {'$in': ['a','b']}}
results = collection.find(body, {'shopid': 1, '_id':0},).batch_size(20).limit(20)
shops = list(results)
The question is that it run about 400ms. But it just take 30ms if we don't care about location.
why and how to fix? please.
You have an index on shopid and cityid, but you search for cityid. Since the index is ordered by shopid first it cannot be used to search by cityid. If you change the index to cityid: 1, shopid: 1, then you will see a performance improvement because your query will be able to search using the index.
after all, i got it.
I just create a index to cityid: 1, shopid: 1, "location" : "2dsphere"
, and then, world peace。
and thanks #tiramisu again.

Right index for slow distinct query

I'm using a distict query with filter defined and query is quire slow on database with 73K items. The query looks like this:
db.runCommand({ "distinct": "companies", "key": "approver",
"query": { "doc_readers": { "$in": [ "ROLE_USER", "ROLE_MODUL_CUST", "ROLE_MODUL_PROJECTS" ] } } })
Query stats is here:
"stats" : {
"n" : 73394,
"nscanned" : 146788,
"nscannedObjects" : 73394,
"timems" : 292,
"cursor" : "BtreeCursor doc_readers_1"
},
It shows that it checks every item to get distinct list of approvers here . Is there a way how to create a better index to speed up things? I have a 3 similar queries on one web page so together they take 1 sec to get data.
Update 1: I have the following indexes
Only the first one is beeing used as stats shows ...
{
"v" : 1,
"key" : {
"doc_readers" : 1
},
"name" : "doc_readers_1",
"ns" : "netnotes.companies",
"sparse" : false
},
{
"v" : 1,
"key" : {
"doc_readers" : 1,
"approver" : 1
},
"name" : "doc_readers_1_schvalovatel_1",
"ns" : "netnotes.companies"
},
{
"v" : 1,
"key" : {
"approver" : 1,
"doc_readers" : 1
},
"name" : "schvalovatel_1_doc_readers_1",
"ns" : "netnotes.companies"
},

MongoDB query for full text search and Geo returning wrong result

When we try to search through mongo cli, we are not getting correct data. Here's the full scenario:
We have the following JSON in a collection:
"_id" : 18348,
"Name" : "Applebee's Neighborhood Grill",
"AddressLine1" : "2545 Scottsville Rd, Bowling Green, KY - 42104, United States",
"loc" : {
"lng" : -86.42583465576172,
"lat" : 36.95203399658203
},
"ProfilePicturePath" : "",
"MarketID" : 92,
"TotalFavorites" : 0,
"PriceRating" : null,
"ProfileType" : "R",
"Cuisines" : [ ],
"Rating" : 4
When we search where we give BOTH Geo Query and full text, we are getting incorrect result. In this case (below) I changed the longitude:
db.rests.runCommand( "text", {search:"Applebee's", filter:{ loc : { $near : [-86.43113708496094,136.963356018066406] , $maxDistance : 1/69 }} } )
I get:
{
"queryDebugString" : "applebe||||||",
"language" : "english",
"results" : [
{
"score" : 0.6666666666666666,
"obj" : {
"_id" : 18348,
"Name" : "Applebee's Neighborhood Grill",
"AddressLine1" : "2545 Scottsville Rd, Bowling Green, KY - 42104, United States",
"loc" : {
"lng" : -86.42583465576172,
"lat" : 36.95203399658203
},
"ProfilePicturePath" : "",
"MarketID" : 92,
"TotalFavorites" : 0,
"PriceRating" : null,
"ProfileType" : "R",
"Cuisines" : [ ],
"Rating" : 4
}
}
],
"stats" : {
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 1,
"nfound" : 1,
"timeMicros" : 92
},
"ok" : 1
}
We have tried with following indexes:
db.rests.ensureIndex( { "locs": "2d" } )
db.rests.ensureIndex({Name: "text",AddressLine1: "text"})
db.rests.ensureIndex({Name: "text",AddressLine1: "text"},{"loc":"2d"})
Perhaps we are doing something wrong? If we do not use Geo Filter and use other filters like Rating etc, its working fine.
Please help
Amit
http://www.aquevix.com
According to the 2.4 documentation, text indexes do not work with $near:
Note You cannot combine the text command, which requires a special text index, with a query operator that requires a different type of special index. For example you cannot combine text with the $near operator.

Filtering mongodb geospatial return data?

I have a geospatial collection that's working well -- given a simple query and data return like this:
> distance = db.runCommand({ geoNear : "geodata_geo", near : [-121.8993988, 36.9771729], spherical : true, maxDistance : range / earthRadius, num : 3 }).results;
[
{
"dis" : 0,
"obj" : {
"CountryID" : 231,
"_id" : ObjectId("4ecea8348044dc9bdd21eda3"),
"cityCode" : "3183347",
"cityID" : 952717,
"cityName" : "Aptos",
"countryCode" : "US",
"countryName" : "United States",
"countyCode" : "US005044",
"countyID" : 5932,
"countyName" : "Santa Cruz",
"**id_geo**" : 952717,
"lat" : 36.9771728515625,
"loc" : {
"lon" : -121.8993988,
"lat" : 36.9771729
},
"lon" : -121.89939880371094,
"regionCode" : "NAm",
"regionID" : 1078,
"regionName" : "North America",
"stateCode" : "US005",
"stateID" : 3725,
"stateName" : "California"
}
},
Is there a way to form this query so that I only return the (list of) id_geo values from within the collection? I've tried several variations but none seem to give me what I need...I know I can handle this programmatically, but was wondering if this was mongopossible...
thanks!
Do you really need geoNear? The docs indicate that "the find() syntax above is typically preferred".
If you're OK with find(), then it's easy. Returning all fields:
db.customers.find({ "addresses.billing_address.location" :
{ $within : { $center : [[-117.15,32.72],0.15] } } }
)
Returning the same documents but only the account_type field:
db.customers.find({ "addresses.billing_address.location" :
{ $within : { $center : [[-117.15,32.72],0.15] } } }, {"account_type" : 1}
)
Try specifying the fields parameter:
db.runCommand({ geoNear : "geodata_geo",
near : [-121.8993988, 36.9771729],
spherical : true,
maxDistance : 45,
num : 3 },
{fields : { "obj.id_geo" : 1 } }).results;
This is documented for the findAndModify command.

Filtering MongoDB geoNear commands with a query

I have a MongoDB collection with the following document in it:
{
"_id" : ObjectId("4eb479a61258ec97acd1034d"),
"places" : [
{
"coords" : [1,0],
"remaining" : 1
},
{
"coords" : [0,0],
"remaining" : 0
},
}
I have also set a compound, multi-location index on {places.coords: "2d", 'places.remaining':1}
I would like to search for all documents that have a place close to [0,0] and also have remaining > 0, and also the coords of the places that matched.
However, running the command
db.runCommand(
{
'geoNear':"mycollection",
near:[0,0],
query:{'places.remaining': {'$gt': 0}},
includeLocs: true
}
)
Returns:
{
"ns" : "test.mycollection",
"near" : "1100000000000000000000000000000000000000000000000000",
"results" : [
{
"dis" : 0,
"loc" : {
"0" : 0,
"1" : 0
},
"obj" : {
"_id" : ObjectId("4eb479a61258ec97acd1034d"),
"places" : [
{
"coords" : [
1,
0
],
"remaining" : 1
},
{
"coords" : [
0,
0
],
"remaining" : 0
}
]
}
},
{
"dis" : 1,
"loc" : {
"0" : 1,
"1" : 0
},
"obj" : {
"_id" : ObjectId("4eb479a61258ec97acd1034d"),
"places" : [
{
"coords" : [
1,
0
],
"remaining" : 1
},
{
"coords" : [
0,
0
],
"remaining" : 0
}
]
}
}
],
"stats" : {
"time" : 0,
"btreelocs" : 0,
"nscanned" : 2,
"objectsLoaded" : 1,
"avgDistance" : 0.5,
"maxDistance" : 1.0000124312194423
},
"ok" : 1
}
i.e. both places, even though the place with coords [0,0] has remaining = 0.
My suspicion was that the query wasn't having any effect but when I run
db.runCommand(
{
'geoNear':"mycollection",
near:[0,0],
includeLocs: true,
query:{'foo':'bar'}
}
)
no places are returned:
{
"ns" : "test.mycollection",
"near" : "1100000000000000000000000000000000000000000000000000",
"results" : [ ],
"stats" : {
"time" : 0,
"btreelocs" : 0,
"nscanned" : 2,
"objectsLoaded" : 1,
"avgDistance" : NaN,
"maxDistance" : 0
},
"ok" : 1
}
Does anyone have any idea what's going wrong? Is what I want even possible with geoNear? Thanks in advance.
It is because that you have places inside the other document as embedded. Mongodb doesn't have the ability(as of now) to return only the sub documents even though the positional operator $ exists. $ operator currently works with update the particular sub documents.
This is the behavior of filtering multi level embedded document, normally the matching filter would return the whole document, not the subsets.
So you need to change your doc structure.Instead storing multiple places inside the doc, split them into separate doc. It will give the ability you wanted.
For more info refer How to make a query in this nested document structure (MongoDB)?