for rest in restaurants.find({},{"restaurant_id" : 0,"name":1,"borough":1, "cuisine":1, "_id":0},{"borough": {$in: ["Bronx", "Queens"]}}).limit(20):
print(rest)
Why am I getting a syntax error at $in?
Updated mongoDB still getting syntax error at $in.
for rest in restaurants.find({"borough":{$in:["Bronx", "Queens"]},{"restaurant_id" : 0, "_id":0}}).limit(20):
print(rest)
According to documentation, find allows only two parameters: Query and projection.
Docs says:
Query: Specifies selection filter using query operators.
Projection: Specifies the fields to return in the documents that match the query filter.
But your query is like:
find({/*empty object*/}, {projection}, {query} )
Using en empty object as query is to get all data, like SELECT * in SQL. So, your query is wrong, because your are trying first get all data, then do a projection and in the end a query.
So, following docs you need something like this:
db.collection.find({
/* Query */
"borough": {
"$in": [
"Bronx",
"Queens"
]
}
},
{
/* Projection */
"restaurant_id": 0,
"_id": 0
})
Also note in projection is only possible indicate the values to be excluded. By default, all values from collection are shown, so you don't have to include. You only need to exclude values you don't want to retrieve.
Related
I cant seem to get the filter clause to retrieve documents from my index using a regex clause. The schema for my index is straight forward, I only have a single field which is both searchable and filterable and is of type Edm.String, called someId (which normally contains a hash value of something) and has sample values like:
someId
k6l7k2oj
k6l55iq8
k6l61ff8
...
I need to be able to extract all values from this field that start with K6 and end with 8. So based on the documentation I am using this in my POST request body
{
"filter": "search.ismatch('/^k6[?]*d$/','someId','simple','all')",
"select":"someId",
"count":"true"
}
and it comes up with nothing.
On the other hand if I simplify and say I only need data where someId starts with K6, I seem to get some success if i just use a wild card.
like this:
{
"filter": "search.ismatch('k6l*','someId','simple','all')",
"select":"someId",
"count":"true"
}
I do get what I am looking for. Question is why does the regex not work with search.isMatch(), what am i missing?
...
Regex is part of the full Lucene syntax; It is not available in the simple syntax. Try changing the third parameter of search.ismatch to 'full'.
Also, did you mean to use search.ismatch or search.ismatchscoring? The latter is functionally equivalent to using the top-level search, searchFields, queryType, and searchMode parameters. The former does not count matches towards relevance scoring.
Your regex does not do what you intend either it seems. I tested your regex with your sample data and it does not match. Try this regex instead:
^k6.{5}8$
It matches a lowercase k6 from the start of the string, followed by 5 characters of anything and finally an 8.
Complete example
{ "filter": "search.ismatch('^k6.{5}8$','someId','full','all')", "select":"someId", "count":"true" }
Thanks to Dan and Bruce.
This exact expression worked for me
{
"filter": "search.ismatch('/k6.{5}8/','someId','full','all')",
"select":"someId",
"count":"true"
}
I am using Parse Server, which runs on MongoDB.
Let's say I have collections User and Comment and a join table of user and comment.
User can like a comment, which creates a new record in a join table.
Specifically in Parse Server, join table can be defined using a 'relation' field in the collection.
Now when I want to retrieve all comments, I also need to know, whether each of them is liked by the current user. How can I do this, without doing additional queries?
You might say I could create an array field likers in Comment table and use $elemMatch, but it doesn't seem as a good idea, because potentially, there can be thousands of likes on a comment.
My idea, but I hope there could be a better solution:
I could create an array field someLikers, a relation (join table) field allLikers and a number field likesCount in Comment table. Then put first 100 likers in both someLikers and allLikers and additional likers only in the allLikers. I would always increment the likesCount.
Then when querying a list of comments, I would implement the call with $elemMatch, which would tell me whether the current user is inside someLikers. When I would get the comments, I would check whether some of the comments have likesCount > 100 AND $elemMatch returned null. If so, I would have to run another query in the join table, looking for those comments and checking (querying by) whether they are liked by the current user.
Is there a better option?
Thanks!
I'd advise agains directly accessing MongoDB unless you absolutely have to; after all, the way collections and relations are built is an implementation detail of Parse and in theory could change in the future, breaking your code.
Even though you want to avoid multiple queries I suggest to do just that (depending on your platform you might even be able to run two Parse queries in parallel):
The first one is the query on Comment for getting all comments you want to display; assuming you have some kind of Post for which comments can be written, the query would find all comments referencing the current post.
The second query again is for on Comment, but this time
constrained to the comments retrieved in the first query, e.g.: containedIn("objectID", arrayOfCommentIDs)
and constrained to the comments having the current user in their likers relation, e.g.: equalTo("likers", currentUser)
Well a join collection is not really a noSQL way of thinking ;-)
I don't know ParseServer, so below is just based on pure MongoDB.
What i would do is, in the Comment document use an array of ObjectId's for each user who likes the comment.
Sample document layout
{
"_id" : ObjectId(""),
"name" : "Comment X",
"liked" : [
ObjectId(""),
....
]
}
Then use a aggregation to get the data. I asume you have the _id of the comment and you know the _id of the user.
The following aggregation returns the comment with a like count and a boolean which indicates the user liked the comment.
db.Comment.aggregate(
[
{
$match: {
_id : ObjectId("your commentId")
}
},
{
$project: {
_id : 1,
name :1,
number_of_likes : {$size : "$liked"},
user_liked: {
$gt: [{
$size: {
$filter: {
input: "$liked",
as: "like",
cond: {
$eq: ["$$like", ObjectId("your userId")]
}
}
}
}, 0]
},
}
},
]
);
this returns
{
"_id" : ObjectId(""),
"name" : "Comment X",
"number_of_likes" : NumberInt(7),
"user_liked" : true
}
Hope this is what your after.
When querying SOLR for results add the minimum and maximum of the field price to that result, in relation to the local parameter tag=price.
Currently, we are using stats:
`stats=true&stats.field={!ex=price}price`
Seeing that a good part of the query time goes into this additional information (judging from debugQuery info), I was looking for a different way to get that information. Several ideas came to mind but none is working for me:
(A) only return min and max from stats, nothing else: I don't find a way to reduce the output of stats. Is there a way?
(B) use json.facet: with the following query I get the min and max price but I can only make it work without local parameters:
json.facet={price_min:'min(price)',price_max:'max(price)'}
fails:
json.facet={price_min:'min(price)',price_max:'max(price)',domain:{}}
"expected facet/stat type name, like {type:range, field:price, ...} but got null , path=/facet"
json.facet={price_min:'min(price)',price_max:'max(price)',excludeTags:price}
"org.apache.solr.search.SyntaxError: Unknown aggregation agg_price in ('price', pos=5)"
json.facet={price_min:'min(price)',price_max:'max(price)',domain:{excludeTags:'price'}}
"Unknown facet or stat. key=domain type=excludeTags args=price , path=/facet"
Can you try a query facet in your json facet, like so:
json.facet={
prices: {
type: query,
q: "*:*",
facet: {
price_min:"min(price)",
price_max:"max(price)"
},
domain: {
excludeTags: price
}
// -- works also without "domain":
// excludeTags: price
}
}
This is one user's notes. I want to query and get only the notes of this use with "activeFlag:1". My query object code is
findAccountObj =
{ _id: objectID(req.body.accountId),
ownerId: req.body.userId,
bookId: req.body.bookId,
"notes.activeFlag": 1 };
But this query returns all the notes, including the ones with "activeFlag:0".
How do I fix this?
If you are on v2.2, use elementmatch operator. v3.2 and above allow aggregation and filter to return a subset of a document.
here is an example Retrieve only the queried element in an object array in MongoDB collection
I'm using solr's stats fields to return some information, and while useful, it contains a ton of data I don't need.
The query:
&stats=true&stats.field=name&stats.calcdistinct=true
returns me each distinct/unique value, but by default, it lists out each unique value that it finds - which in this case, I don't want - I only want it to return the number of results found. This is fine when the distinct count is under 100 or so, but when if it's 56,000, I am forced to return 56,000 distinct values to the browser, which is expensive:
"stats":{
"stats_fields":{
"name":{
"min":"Alan",
"max":"Zeke",
"count":197890,
"missing":0,
"distinctValues":["Alan",
"Bob",
"Matt",
"Chan",
"Peter",
"Zeke"],
"countDistinct":56872, // <--- 56,872 lines get returned...
"facets":{}}}}}
Is there a way for me to tell solr I only want it to return
stats --> stats_fields --> name --> countDistinct and not any other stats attribute, like so:
"stats":{
"stats_fields":{
"name":{
"countDistinct":56872,
}}}}
Add a local parameter to the query; e.g.:
&stats=true&stats.field=name&stats.calcdistinct=true&{!distinctValues=false}name
If stats.calcDistinct is true, the "countDistinct" and "distinctValues" statistics will be computed and included the response so you need to disable distinctValues in order to exclude the list of values from the response.