Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$in operator to search tagged documents #42

Open
rochacbruno opened this issue Sep 26, 2017 · 3 comments
Open

$in operator to search tagged documents #42

rochacbruno opened this issue Sep 26, 2017 · 3 comments

Comments

@rochacbruno
Copy link
Contributor

rochacbruno commented Sep 26, 2017

I have a document like this

{
 '_id': '3c7df42e91c611e7bf575ce0c5482b4b',
 'authors': ['Bruno Rocha'],
 'authors_slug': ['bruno-rocha'],
 'category': 'python/flask',
 'date': datetime.datetime(2017, 9, 4, 20, 10, 26),
 'published': True,
 'slug': 'simple-login-extension-for-flask',
 'tags': ['python', 'flask', 'pythonplanet', 'pyplanet', 'new'],
 'title': 'Simple Login Extension for Flask',
}

It has a 'tags': ['python', 'flask', 'pythonplanet', 'pyplanet', 'new'] and I have more documents with tag python

When I search using {'tags': 'python'}

col.find({'tags': 'python'}).count()
25.09 22:19:22 tinymongo.tinymongo DEBUG    query to parse2: {'tags': 'python'}
25.09 22:19:22 tinymongo.tinymongo DEBUG    query: {'tags': 'python'} prev_query: None
25.09 22:19:22 tinymongo.tinymongo DEBUG    conditions: tags python
25.09 22:19:22 tinymongo.tinymongo DEBUG    c: QueryImpl('==', ('tags',), 'python')
25.09 22:19:22 tinymongo.tinymongo DEBUG    new query item2: QueryImpl('==', ('tags',), 'python')
0

Ok that is expected so lets use {'$in': 'python'}

col.find({'tags': {'$in': 'python'}}).count()
25.09 22:20:34 tinymongo.tinymongo DEBUG    query to parse2: {'tags': {'$in': 'python'}}
25.09 22:20:34 tinymongo.tinymongo DEBUG    query: {'tags': {'$in': 'python'}} prev_query: None
25.09 22:20:34 tinymongo.tinymongo DEBUG    conditions: tags {'$in': 'python'}
25.09 22:20:34 tinymongo.tinymongo DEBUG    c: None
25.09 22:20:34 tinymongo.tinymongo DEBUG    query: {'$in': 'python'} prev_query: tags
25.09 22:20:34 tinymongo.tinymongo DEBUG    conditions: $in python
25.09 22:20:34 tinymongo.tinymongo DEBUG    c: None
25.09 22:20:34 tinymongo.tinymongo DEBUG    new query item2: None
0

or with a list: {'$in': ['python', 'flask']}

col.find({'tags': {'$in': ['python', 'flask']}}).count()
25.09 22:21:09 tinymongo.tinymongo DEBUG    query to parse2: {'tags': {'$in': ['python', 'flask']}}
25.09 22:21:09 tinymongo.tinymongo DEBUG    query: {'tags': {'$in': ['python', 'flask']}} prev_query: None
25.09 22:21:09 tinymongo.tinymongo DEBUG    conditions: tags {'$in': ['python', 'flask']}
25.09 22:21:09 tinymongo.tinymongo DEBUG    c: None
25.09 22:21:09 tinymongo.tinymongo DEBUG    query: {'$in': ['python', 'flask']} prev_query: tags
25.09 22:21:09 tinymongo.tinymongo DEBUG    conditions: $in ['python', 'flask']
25.09 22:21:09 tinymongo.tinymongo DEBUG    c: None
25.09 22:21:09 tinymongo.tinymongo DEBUG    query: {'tags': 'python'} prev_query: None
25.09 22:21:09 tinymongo.tinymongo DEBUG    conditions: tags python
25.09 22:21:09 tinymongo.tinymongo DEBUG    c: QueryImpl('==', ('tags',), 'python')
25.09 22:21:09 tinymongo.tinymongo DEBUG    query: {'tags': 'flask'} prev_query: None
25.09 22:21:09 tinymongo.tinymongo DEBUG    conditions: tags flask
25.09 22:21:09 tinymongo.tinymongo DEBUG    c: QueryImpl('==', ('tags',), 'flask')
25.09 22:21:09 tinymongo.tinymongo DEBUG    new query item2: QueryImpl('or', frozenset({('==', ('tags',), 'python'), ('==', ('tags',), 'flask')}))
0

I checked the source code and currently the $in operator only works in the reverse way, it works currently to match a single field against an array of possibilities. But not to check an array against a single value or array.

@rochacbruno
Copy link
Contributor Author

Test case for future implementation

db.tags.insert({"tags":["red", "tall", "cheap"]});
db.tags.insert({"tags":["blue", "tall", "expensive"]});
db.tags.insert({"tags":["blue", "little", "cheap"]}); 

# find all blue
db.tags.find({tags: "blue"})

# find all blue and cheap
db.tags.find({ tags: { $all: ["cheap", "blue"] } } )

# find all not blue
db.tags.find({tags: { $ne: "blue" } })

# find all "blue" and "cheap" but not "red" and not "tall"
db.tags.find({ $and: [ {tags: { $all: ["blue", "cheap"] } }, { tags: { $nin: ["red", "tall"] } } ] })

@rochacbruno
Copy link
Contributor Author

I did a workaround saving a string version of my tags as {'tags_string': ',python,flask,other,another,'}

and querying with

col.find({'tags_string': {'$regex': '.*,python,.*'}})

@rochacbruno
Copy link
Contributor Author

@schapman1974 @jjonesAtMoog can you guys add hacktoberfest label to this issue please?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant