MD10
MD10

Reputation: 1521

mongodb find a pattern of an input

I need to find all the results that start with certain input for example for the inputs: "Paul", "pau", "paul Gr", "Paul Green", "Paul Gree" , "Pel", "pele", "joh","john" etc.. The search has to be case insensive.. it suppose to return all of these(the input search string is at least 3 characters long):

[
  {
    "_id": ObjectId("5e6ffe413f71835ae3aa4b60"),
    "f": "Paul",
    "id": 11811,
    "l": "Pelè",
    "r": 64
  },
  {
    "_id": ObjectId("5e6ffe413f71835ae3aa4b65"),
    "f": "paul",
    "id": 11811,
    "l": "walker",
    "r": 64
  },
  {
    "_id": ObjectId("5e6ffe413f71835ae3aa4b66"),
    "f": "johnny",
    "id": 11811,
    "l": "Green",
    "r": 64
  }
]

tried to do the following:

 contain_searched_term_players = list(db.players_collection.find({'$or': [{'f': {'$regex': searched_player_name_string, '$options': 'i'}},
                                                                         {'l': {'$regex': searched_player_name_string, '$options': 'i'}},
                                                                         {'c': {'$regex': searched_player_name_string, '$options': 'i'}}]}).sort([{'r', -1}])

but it doesnt work for "Paul Green"

searched_player_name_string is the given input(the inputs above, for example Paul Green)

Upvotes: 0

Views: 64

Answers (2)

Belly Buster
Belly Buster

Reputation: 8814

Split your input in separate strings, run the query on each and append the results together (checking first it's not already found), Finally sort the results:

searched_player_name_string = 'Paul Green'
found_players = []

for regex in searched_player_name_string.split():
    contain_searched_term_players = db.players_collection.find({'$or': [{'f': {'$regex': regex, '$options': 'i'}},
                                                                             {'l': {'$regex': regex, '$options': 'i'}},
                                                                             {'c': {'$regex': regex, '$options': 'i'}}]})
    for player in contain_searched_term_players:
        # The next line avoids creating duplicate answers if there are multiple matches for the same player
        if player['_id'] not in [ o['_id'] for o in found_players ]:
            found_players.append(player)

# Sort the output by "r" - highest first
pprint.pprint(sorted(found_players, key=lambda o: o['r'], reverse=True))

Upvotes: 0

Valijon
Valijon

Reputation: 13103

You need to provide correct Regex for query condition

^(Paul Green|Paul Gree|Paul|paul|pau|Gr|pele|Pel|john|joh)

RegexPlayground

searched_player_name_string = "^(Paul Green|Paul Gree|Paul|paul|pau|Gr|pele|Pel|john|joh)"
result_cursor = db.players_collection.find({
  "$or": [
    {
      "f": {
        "$regex": searched_player_name_string,
        "$options": "i"
      }
    },
    {
      "l": {
        "$regex": searched_player_name_string,
        "$options": "i"
      }
    },
    {
      "c": {
        "$regex": searched_player_name_string,
        "$options": "i"
      }
    }
  ]
})
searched_player_name_string = list(result_cursor)

MongoPlayground

Upvotes: 1

Related Questions