-2

I am working on a online booking system of items.

I am using mongo to store booking and item details

Item

{
  id: "3",
  "name": "",
  "description": "",
  "extra": [{}]
}

Booking

{
  "id": "",
  "itemId":""
  "startDate": millis,
  "endDate": millis,
  "status": "",
  "userId": ""
}

I have to implement search b/w dates. The search should return only available items for the specified period. How can I build a scalable search for this? I am planning to use elastic also for search. Any suggestion related to new technology also welcome.

sabu
  • 1,969
  • 4
  • 18
  • 28

2 Answers2

0

I'd suggest making the booking the base object and putting the item info inside it. That is to say:

Set up mapping:

PUT bookings
{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "item": {
        "properties": {
          "id": {
            "type": "keyword"
          },
          "name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword"
              }
            }
          },
          "description": {
            "type": "text"
          },
          "extra": {
            "type": "nested"
          }
        }
      },
      "startDate": {
        "type": "date",
        "format": "epoch_millis"
      },
      "endDate": {
        "type": "date",
        "format": "epoch_millis"
      },
      "status": {
        "type": "keyword"
      },
      "userId": {
        "type": "keyword"
      }
    }
  }
}

Ingest the simplest booking

POST bookings/_doc
{
  "item": {
    "id": "987"
  },
  "startDate": 1587110540025,
  "endDate": 1587220730025
}

Restricting the *Date fields and only returning the corresponding item:

GET bookings/_search
{
  "_source": "item",
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "startDate": {
              "gte": "17/04/2020",
              "format": "dd/MM/yyyy"
            }
          }
        },
        {
          "range": {
            "endDate": {
              "lte": "18/04/2020",
              "format": "dd/MM/yyyy"
            }
          }
        }
      ]
    }
  }
}

Note that although our date fields are defined as epoch_millis, we can still query using human-readable date strings, provided we specify the format. You can of course use milliseconds if you prefer.

Joe - GMapsBook.com
  • 15,787
  • 4
  • 23
  • 68
0

While indexing the items to Elasticsearch you can check bookings. Think that, you are indexing items and you get the item from Mongo. Also, you can get the bookings for this item and you can add a field like bookingCount inside the item document of Elasticsearch. While searching you can use bookingCount field to search without booking items.

In generally, the indexing is async operations. You can use queue. So, this will reduce latency for the user operations. And, you can do what you want in there. You can get a summary with bookings and you can put inside the item.

{
  id: "3",
  "name": "",
  "description": "",
  "extra": [{}],
  "bookingCount": "",
  "bookingsByStatus": {
    "status_1": 1233,
    "status_2": 1233,
    ...
  }
}

But this is a business decision. And after any update of items and booking, you need yo update the item from Elasticsearch index. Also, you can use other solution like mentione by @jzzfs.

hkulekci
  • 1,894
  • 15
  • 27